Technically a theme can be installed onto any Drupal site, but it never quite works this way in real life. In this lesson we'll create a playground so that we can try out our theme before deploying it to a live server. We'll start by installing Drupal and adding some “fake” content and menus with the devel generate module. For these tasks we'll use Drupal's default theme, Bartik. By the end of this lesson you will be able to install Drupal in an environment where a development version of the theme can be safely tested.
Additional resources
One of the most time consuming things a content editor can be forced to do is resize images before creating their content. Fortunately we can get Drupal to do the resizing for us. It's not perfect—it's just a plain resize, but it's enough for most basic sites. By the end of this lesson, you will be able to configure Drupal to resize images to your specification when they are uploaded using the image field type.
It's pretty typical for a site to have one or two pieces of content that need to be easily edited, but also aren't nodes. For example: text in the footer. There are a number of ways to create this content. We'll use blocks to create this content as this is the easiest way to place content into a specific region without additional helper module. By the end of this lesson you will be able to create custom blocks, and place them into specific regions within your Drupal theme.
A base theme is someone's idea of a really great starting point. It might include the stub files for CSS overrides, template files which bring Drupal core's markup up-to-date with HTML5, useful theme overrides which create new template variables. In other words: a base theme can provide you with a lot of really great stuff! The first version of the Domicile Theme used the NineSixty base theme—just enough for a simple site, but not so much overhead that it was complicated to learn. This version of the theme doesn't use a base theme. That's because, thanks to Sass, we'll be able to get almost all of the power of the NineSixty base theme through a gem plug-in. In this lesson you will learn which folders are typically used to keep Drupal themes neat and tidy.
A theme is comprised of a collection of related files. Our completed theme will have CSS and PHP (with HTML fragments). To ensure all of these files are loaded, we need to tell Drupal where to find them, by listing the files in the theme's .info file. To begin working with our theme's info file we'll start with the only values which are required: name, version of Drupal core this theme can be applied to. We'll also add a few recommended pieces of information: description of the theme, the template engine, and a screen shot for easier selection of the theme from the administrative area. By the end of this lesson, you will be able to create an info file for a theme, and explore the relevant drupal.org handbook pages for more information on refining your theme's info file.
Our main focus for the Domicile theme is restyling Drupal's markup with CSS. Although it is tempting to put all of your CSS into a single file, things can quickly grow out of control. In our theme we'll break our CSS into smaller stub files to make the theme easier to maintain using the file naming conventions for Drupal 8.By the end of this lesson you will be able to incorporate CSS files into your theme via the theme's .info file.
Additional resources
Drupal uses a series of nested template files to build out the rendered HTML pages we see in our browser. The template file page.tpl.php holds markup between <body> and </body> tags. We talked about the nested nature of template files in Lesson 3: Theming by Component.
In this lesson we will:
- create the file page.tpl.php
- add the relevant markup, and CSS classes for our grid framework
- insert relevant PHP variables so that Drupal can render each of its page components.
By the end of this lesson you will be able to create, or adapt, a page.tpl.php file to suit the conventions you identified in your style guide.
Designs often have a few elements which don't need to be easily edited and can essentially be "hard wired" into the template files. In our design there are three or four images which fall into this category. In this lesson we'll edit the page.tpl.php file to insert our design assets from Lesson 5: Extract Design Assets. By the end of this lesson you will know which variables can be used in a template file to ensure the correct directory is always used for hard-coded image files.
It's always smart to do your development work in a local environment, but eventually you will need to upload your theme your server. In this lesson we'll upload our theme to our web server using Filezilla. By the end of this lesson you will know which folder your theme needs to be uploaded to, and at least one application suitable for uploading files.
Additional resources
Once your theme is uploaded you still need to enable it before it will be applied to your site. By the end of this lesson you will be able to enable new themes for your Drupal site.
Once all of the elements are in place, it's time to get down to the real work of theming the components. In this lesson we will:
- use our style guide and checklist to find each component
- check to see if the style looks "right"
- troubleshoot broken styles so that each component looks as good as the designer's original, static files
By the end of this lesson you will be able to identify elements on a rendered Drupal page which do not have the correct styles applied, determine the source of the problem, and alter the markup or styles to correct the output displayed in a browser.
To go from design to theme we worked through three major steps: building a style guide; building out Drupal; and finally applying the style guide to Drupal. In this lesson we'll review each of the steps outlined in this learning series:
- creating a style guide with base rules, layout rules, and component rules
- extracting design assets
- configuring Drupal
- creating theme files
- debugging components from within Drupal
By the end of this lesson you will be able to outline the process needed to transform a static design file into a functional Drupal theme.
This learning series covered just the tip of the theming iceberg. Hopefully you're now feeling motivated to learn even more about theming. In this lesson we will review some of the other topics you will want to explore next including: advanced theming techniques, using a base theme, such as Omega, layout modules. By the end of this lesson you will by able to identify which videos you should (or could) watch next to learn more about theming Drupal.
Probably the most common use case for view modes is teaser nodes. Or, a node being rendered in the teaser view mode. View modes allow entities to be displayed different depending on context, and also allow other modules like Field API that participate in the entity rendering process to adjust their behavior depending on the requested view mode.
In this lesson we’re going to take a look at an ‘authenticated’ view mode that we can use to adjust the display for any authenticated users. Then we’ll update Entity Controller class and make use of this new view mode in our ::view() method.
NOTE: in the video Joe forgot to change the 'member' label to "Member" and then later in the video when we view it in the UI it is corrected. The sample code included with this video has the correct label.
In this lesson we're going to take a more in-depth look at the UI controller we used earlier to create our administrative UI for the entity. We'll walk through how the controller adds menu paths and the like, without us needing to do any extra work, and then clean up our form-builder functions by overriding the UI controller's method, so that we can gain control of the name of the function that's called.
This lesson takes a look at exposing the data in our entities to views. Lucky for us the entity API handles a lot of this for us. We’ll take a look at what we get for free, using the EntityDefaultViewsController class provided by Entity API module. We'll also discuss ways that we can customize this controller, which we'll tackle in a later lesson.
"There's a module for that."
You've probably heard this before. Many times you can find a module that provides the functionality you need — or at least pretty close to what you need. Drupal's contributed module projects number in the thousands, but what if there isn't a module for your use case? You just might need to build a module for that.
In this series, you will learn about the tools and resources available to Drupal developers, including where to find documentation and what APIs are available to you, both on drupal.org and api.drupal.org. We'll take a look at the Devel module and learn how to use it to inspect the variables, objects, arrays and other things at work under the hood of Drupal 7.
You'll build several different modules that explore and interact with Drupal's various systems and API, including:
- Form API
- Menu system
- Hooks
- Render API
- Theme system
- Database API
Over the course of this series you'll be able to:
- Describe the anatomy of a module
- Implement common hooks
- Write more secure code
- Interact with Drupal's menu system
- Create and alter forms
- Peform CRUD operations on a database
This series starts with the basics and moves you step-by-step to more advanced concepts. Even if you are quite comfortable with PHP but are struggling to understand how to appropriately interact with Drupal 7's API, the lessons in this series can help you develop "The Drupal Way."
Additional resources
In order to make the most of the entity APIs integration with other modules, such as Views, we need to describe the properties of our entity in more detail. The API can infer some information about a property based on our schema but we need to tell it that the integer stored in the updated_at column is actually a timestamp. We will do this by implementing hook_entity_property_info()
and describing each of our entities properties. With these definitions in place you will be able to use the formatters in Views much like you would for individual fields on content types provided by core.
Note: Before you implement hook_entity_property_info()
the API makes an educated guess about each property but once you've defined a single property, the API expects you to define all of the properties for your entity. Use the .install
file in your module to get a complete list of the properties you need to define with hook_property_entity_info
. You can also define additional properties that aren't mapped to fields in the database (these can be used for static properties).
Additional resources
If you've done any module development, you're probably familiar with hook_node_view and Drupal's arrays of doom. In this lesson we'll show you how to get easier access to the same information using entity metadata wrappers. We will use the entity_metadata_wrapper function to retrieve a new EntityMetaDataWrapper
object that provides an interface for easily accessing an entities property and field values. We'll use the getPropertyInfo
method to expose information about individual properties, and the getIterator
method to access fields that contain multiple values, such as tags. You'll see that by using meta data wrappers you can also access properties on referenced entities, such as the email address of the author of a node, without having to load that information independently.
Metadata wrappers also provide a consistent way to access properties common to all entities. For example, every entity in Drupal has a unique ID property or a human readable label, but these properties often have different names. User name vs. node title. Metadata wrappers allow you to access this information in a consistent way.
Additional resources
Revisions are an important concept in a content management system. Keeping track of all the edits that have been made to a particular entity over the course of its lifetime. A paper trail or sorts. This lesson takes a look at what is required in order to make our Entities support revisions.
If you've worked with Drupal's node system and enabled revisions then you've seen Drupal's basic revision handling in action. Every time you save a node, it creates a new version of that node. You can roll back to previous versions and keep track of how a piece of content has changed over time. Entity API also supports the concept of revisions and in this lesson we're going to take a look at adding revision support for our video entities.
In order to take advantage of this feature, we'll need to modify our database schema to accommodate storing multiple versions of the same entity. We'll move all fields that we want to make "revisionable" into a separate table and set up a new unique version ID field so that we can keep track of revisions.
Then we will update our hook_entity_info
implementation to tell the API that we want to use the revision system and make some changes to the code in our VideoEntityController
so that when an entity is updated we save a revision instead of overwriting the current data.
Finally we'll need to write a simple UI for viewing older versions of our video entity because the Entity API does not provide us with this code by default.