In this chapter Karen Stevenson explains all the pieces that make up an Organic Group content type. Show explains how organic groups adds the necessary fields to make this happen while demonstrating the necessary settings when building your content types. She also covers the content type used for group content as it is different than the group itself. To start the video off she goes over install the necessary modules for the first part of this series.
Note: There have been significant changes to Organic Groups since this lesson was made. Though we would like to revisit this series to update it, we have no current schedule to complete that. The best place to figure out what has changed and why, would be the Organic Groups issue queue on Drupal.org (http://drupal.org/project/issues/search/og).
Additional resources
In this lesson Joe will explain what an entity is and provide a little bit of history about how they came into being. We’ll also learn about some of the differences between custom entities and nodes (which happen to be a type of entity) and when, and why you might want to choose to write your own custom entities instead of using the node system or a more traditional datastore.
Entities were introduced in Drupal 7 as a way of taking the things that people loved about nodes + CCK in Drupal 6 and applying them to other types of data like users, comments, and taxonomy terms. The Entity API in Drupal 7 provides a set of common functions and classes to make it easier for developers to create their own custom entity types or to work with existing ones in a generic way. The API in Drupal core however is still missing some really useful tools and is supplemented by the Entity module in Drupal contributed which we'll make heavy use of throughout the series.
In this series we'll learn about the interplay between Entities, Entity Types, Bundles, and Fields and how to write custom code to deal with each of these things. The Entity API demo site files that we use in this series are all located in the Lullabot GitHub, as well as in zip files attached to the respective video pages, under the Downloads tab.
This series covers:
- What entities are and how they fit into the Drupal ecosphere
- EntityFieldQuery
- Entity classes, what they do and how to override them
- Providing an admin UI for adding/editing and deleting entities from Drupal
- Making entities fieldable
- View modes
- Creating custom UI's for dealing with entities
- Describing entity properties to Drupal
- Views integration for entities
- Entity Metadata wrappers
- Making entities revisionable
And much much more. This series assumes that you're already familiar with the basic tenets of writing modules for Drupal and makes use of things like hook_menu() without spending time explaining them. If you're not familiar with Drupal module development, you might want to brush up by watching our Module Development for Drupal 7 first.
Additional resources
Entity API Demo site files on GitHub
Entity module at Drupal.org
This lesson will explore the use of EntityFieldQuery to retrieve lists of entities from Drupal without directly querying the database which can be problematic in a system where the underlying schema can change depending on configuration settings in the user interface. Again focusing on writing code that will work with any entity in Drupal and isn't hard coded to your particular setup.
Additional resources
In the next set of lessons we're going to be writing to the code to create our own custom entity type. The goal is to create a video entity that stores embed codes for YouTube videos and allows us to display the videos on our site. In this scenario we don't want all the overhead that comes with using the node system, like comments for example, so instead we're going to write our own custom entity for storing the data. We're going to take a look at the completed entity type that we're attempting to build and just walk through all the various components. We'll take a look at creating/updating, and deleting a video via the UI, and also the views integration and fieldability of our custom video entities.
This lesson introduces students to Entity classes and illustrates what each of the main Entity classes does, followed by a more in depth look at the CRUD operations provided by the base entity class, and finally demonstrates overriding the default Entity class with our own custom Entity object to define a defaultUrl() for our entities and a new implementation of hook_menu where we can view an entity.
Note: At the end of the this video code is added to hook_entity_info() that references a VideoEntityUIController
class, however, the definition of that class is in our sample code, but was not shown being added here. And it is necessary to follow along with the videos. If you're following along you'll want to add the following code to the bottom of your videoasset.module file. If you're curious about what it does it's explained in the last part of this video.
/**
* Our custom controller for the admin ui.
*/
class VideoEntityUIController extends EntityDefaultUIController {}
Additional resources
Update your hook_entity_info implementation to take advantage of the Admin UI provided by the Entity API and quickly provide users of your site access to all the Entity CRUD operations via the UI. The API gives us a really good head start but we still need to write some code in order to provide a useable form for administrators. The API doesn’t make any assumptions about things like validating input so we also need to take care of that ourselves.
This video adds a new permission that allows privileged users administer our new videoasset entities. If you're following along as a user other than user 1 you'll need to make sure you give yourself the proper permissions. In the video, I'm logged in as the user with the ID of 1 so I'm just granted the permissions automatically.
Note: If you're following along with the videos in sequence there's an error that needs correcting. At the end of the previous video code was added to videoentity_entity_info()
that references a VideoEntityUIController
class, however, the definition of that class was not added. Which, will cause a PHP error because the class is missing.
In order to correct this error, you'll want to add the following code to the bottom of your videoentity.module file. This just ensures that the class is defined so that there are no errors. If you're curious about what it does it's explained in the last part of the previous video.
/**
* Our custom controller for the admin ui.
*/
class VideoEntityUIController extends EntityDefaultUIController {}
In a later tutorial in this series, we'll customize the form for our video entity by adding more code to this class.
Note: At 14:10 on line 36 this line is added:
'#value' => isset($VideoAsset->id) ? t('Update video asset') : t('Save video
asset'),
It should be:
'#value' => isset($video->id) ? t('Update video asset') : t('Save video
asset'),
So far we’ve seen that you can use entity_load and entity_view to display your entity. But what if you want more control over how your content gets rendered? In this lesson we’ll take a look at overriding the buildContent() method of our entity controller to spruce up the output a bit. We'll also overrid the save() method of the controller in order to populate the created_at and updated_at fields automatically when saving a video entity.
Note: In order to improve upon the security of the code in this lesson you'll want to make sure you're escaping all user input properly. The following code:
$build['embedcode'] = array(
'#type' => 'markup',
'#markup' => '<iframe width="560" height="315" src="http://www.youtube.com/embed/'. $entity->embedcode . '" frameborder="0" allowfullscreen></iframe>',
);
Should be updated to use the check_url() function when outputting $entity->embedcode
to ensure that user entered content is safe for use in the context of a URL.
$build['embedcode'] = array(
'#type' => 'markup',
'#markup' => '<iframe width="560" height="315" src="http://www.youtube.com/embed/'. check_url($entity->embedcode) . '" frameborder="0" allowfullscreen></iframe>',
);
Bundles are an implementation of an entity type to which fields can be attached. In this lesson we’ll take a look at configuring a single bundle type for our entities in order to allow us to make them fieldable by hardcoding the bundle information into hook_entity_info(). This is the most basic implementation of bundles. Then we’ll look at adding the ability to attach fields to our newly created bundle.
Because Omega doesn't make assumptions about your layout, it comes with lots of options and plenty of regions to work with. This is great but also has some down falls espcially if you are converting an exisiting theme that just doesn't need as many regions and zones. Along with removing regions you may need to add some as well. In this lesson we will demonstrate:
- Adding a region
- Removing regions
- Placing content into these regions
- Cleaning up the .info file
Once this is complete, we now have our converted theme setup just as it was before when it comes to the grid system and some blocks in place to make sure the layout is looking good.
NOTE: Kyle initially sets a position, but not the weight, of the footer_bottom region in this video, and then you'll see that he catches the mistake, and fixes it to have a weight of 3.
This chapter walks through the process of adding links to the contextual drop-down widgets new in Drupal 7. It also shows how using menu autoloaders can help simplify the code that you write in your page callback function since you won't have to do extra checking on the data.
As a note, if you are wondering why we started our function with an underscore (_), naming functions with an underscore in front of the name is a common convention in Drupal that sort of implies that "this function is for internal use by this module only" and shouldn't be called by itself. It's also a nice way to ensure that your internal functions are not colliding with the namespace of a hook or another module. Here's a good blog post about naming things.
Features is a module which generates modules for us. You can then extend that module just as you would any other Drupal module. In this video we'll add some additional code to our feature to make it more complete for our needs, outside of the realm of what Features itself can provide.
The features module (and the drush command) are pretty smart about not overwriting custom changes, and your chances of overwriting your custom code are pretty slim. When features exports a module it creates a .module file with only one line of code in it. Which is an include for another file: mymodule.features.inc. Features then puts all of the automatically generated code into this included file. When you regenerate or update a feature it just uses the existing mymodule.module file which maintains any code that you wrote, and then regenerates the mymodule.features.inc and associated files.
Additional resources
Features project (Drupal.org)
Introduction to Drush Series (Drupalize.Me)
https://github.com/DrupalizeMe/drupalize-lullablog (GitHub.com)
Login Redirects
FreeThis screencast shows how to set up Rules to mimick parts of the Login Destination module. It covers:
- How to redirect administrators to the content admin page on login
- How to redirect non-adminsitrators to the front page on login
- That you need the “force redirect” option when redirecting on login (yes, really!)
- Some words about utilizing user permissions instead of user roles for conditions
Additional resources
Rules guide (Drupal.org)
Components
FreeWhy creating Rules components? Here is why!
- You can reuse and simplify configuration
- You can export each component individually
- You can use rules components to perform conditions from within actions
- You can execute components manually for easier debugging (or just for the sake of executing their actions)
An important aspect of components is that they have variables – parameters that must be sent to the component when executing it.
Additional resources
Rules guide (Drupal.org)
This series on Learning the Rules framework was produced by Johan Falk of nodeone.se, and it will present some basic and advanced usage of the Rules framework.
The Rules module helps decrease the need for custom coding. Johan starts with an empty sandbox site. He enables the 3 related Rules modules, and the modules they depend on. Now, we see what it can do for our site by creating some reaction rules. This isn’t just an introduction – you actually get into the mechanics of using Rules right away.
Additional resources
- Rules module — Drupal.org
- Rules guide (Drupal.org)
This tutorial guides you on a quick safari through the actions, conditions and events provided by Rules core. It covers:
- A quick look at some actions provided by Rules
- A quick look at conditions provided by Rules
- A quick look at events provided by Rules
- Some words about data objects being provided to Rules by the triggering events
- Some words about multiple events in one rule limiting the available data (rather than expanding)
Additional resources
Rules guide (Drupal.org)
This screencast presents a way to automatically create the article promotions used in the previous screencast. Topics covered are:
- Using the after new content has been created event, which does provide content NID
- Working with rule set components.
- Creating new entities with Rules.
- Setting field values in new entities – even complex fields like images.
- Force-saving entities, for example to get node IDs.
Additional resources
Rules guide (Drupal.org)
James Sansbury defines Features (a module that helps organize site components and applications for specific use cases), as distinct from Nodes and other forms of site content.
Prerequisites
This series assumes that you can install Drupal 7, create a basic content type, create a basic view, and use Drush. See the following resources if you need a refresher:
- Create a New Content Type
- Creating a New View
- Introduction to Drush series
- Installing Drupal with Drush
Additional resources
Features project (Drupal.org)
Goes through the process of attaching a views display to an existing view. In most cases this is done when the two views are closely related, but are displaying or highlighting different information. In this case, we'll set up a full teaser view of the latest job posting and display that at the top of the table, and we'll also create an offset on the original view so as to not show duplicate content on the attached view.
This video series will continue the Job Board example from the Fields for Site Builders series where we will discover ways to display all of the job postings, allow people to find the one they are looking for and easily apply for it.
Goes through the process of creating dynamic views with contextual filters by taking the content ID (i.e. the node it) from the URL and inserting that value as an argument for the views query. In the end, we're able to create a tab that shows all of the job applications for a particular job and have that view show up on the related job posting node.
This video series will continue the Job Board example from the Fields for Site Builders series where we will discover ways to display all of the job postings, allow people to find the one they are looking for and easily apply for it.