You can create your Panels layouts with HTML and CSS that can then be selected in the Panels UI.
In this lesson...
- Create a two-column, 60/40 layout
- Use existing layout to quickly get started
- Apply new layout to custom home page
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
Creating pages with Panels involves a lot of configuration which can take a lot of time and effort. In order to avoid re-doing all that work on another instance of the site, we can export this configuration into code using Features and deploy it in the usual way (using git or FTP).
In this lesson, we will:
- Export a custom panels page
- Take inventory of all panes
- Create a new Feature to export configuration
By the end of this lesson, you will be able to export a basic panel page configuration that contains a View using Features.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
With mini-panels, you can build portable panels components and place them as blocks in regions of your theme.
In this lesson...
- Build a 3-column mini-panel
- Place a menu in each column
- Place the mini-panel in the footer region as a block
By the end of this lesson, you will be able to build a mini-panel and understand how to place it in a region using the block administration page.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
Panelizer is a powerful module that allows you to attach panels to any entity and view mode in Drupal. You can create default templates for all content in a content type, for example, or you can create one-off pages with unique layouts and content panes.
In this lesson...
- Walk through Panelizer admin UI
- Panelize Article content
- Set up default Panelizer template
- Override versus Update Default Template
By the end of this lesson, you should be able to configure Panelizer settings, enable Panelizer for a content type, and understand the benefits and limitations of creating one-off pages that override the default template versus updating the default template.
Enabling the Panels In-Place Editor is recommended for this lesson.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
Panels provides export code that you can copy and paste into a module or directly import into another instance of the site.
In this lesson, we will:
- Export a panels page using Panels UI
- Import a panels page into another instance of site
By the end of this lesson, you will understand where to find the export code for a panel and be able to simply and quickly import it into another copy of your site.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Podcast 45: Keeping Up with Drupal News
Blog postThis week's podcast, Episode 45: Keeping Up with Drupal News, gets into the why and how of the flow of Drupal community information.
Welcome Betty Tran
Blog postWe're welcoming a new member to the Drupalize.Me team this week! Say hello to Betty Tran.
Stylizer enables site editors to change the styles of panel pane backgrounds, content, text styles, borders, and heading styles. It provides an extensive settings form, including a live preview and integration with the Color module, for point-and-click color picking.
In this lesson, we will:
- Identify style options provided by Panels
- Enable Stylizer module
- Change Styles of a Panel Pane and Heading using Stylizer
By the end of this lesson you should have a good idea of whether or not you want to enable Stylizer on your Panels-based site and if you do, how to access and use it.
Stylizer module comes packaged with CTools.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
Views Content Panes is a module that comes packaged with Panels. It provides a new type of Views display called a Content Pane that enables you to pass off Views configuration to the Panel Pane.
In this lesson, we will:
- Enable Views Content Panes module
- Build a View using Content Pane display
- Explore Pane Configuration in Views
By the end of this lesson, you will have a better idea of why you will want to use content panes in Views whenever you are placing Views in Panels.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
We'll use Page Manager, Panels, and Views to create a customized user account page that features articles authored by the user whose account is being viewed.
In this lesson...
- Build a view of articles with a contextual filter
- Create a customized user account page
By the end of this lesson, you'll walk away with ideas for how to create your own customized user account page.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
In a Views Content Pane display, it's possible to use exposed or contextual filters as panel pane configuration. We'll walk through this process and why you might want to utilize this feature of content panes.
In this lesson...
- Add an exposed filter to a view
- Use the exposed filter as panel pane configuration
- Place the same view twice with different configuration
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
The default taxonomy term page provided by Drupal leaves much to be desired. If a taxonomy vocabulary has multiple levels, but content is only tagged with only the child term and not the parent, parent term pages are left with no content listed on them, despite the fact that there is content tagged with terms below it.
In this lesson...
- Create a taxonomy vocabulary with two levels of hierarchy
- Enable the Taxonomy Term Template
- Build a custom term page for each level of hierarchy
By the end of this lesson, you'll know how to create better taxonomy term pages using Views, contextual filters, and Panels.
Demo site log in:
- Navigate to /user
- Login with admin/admin
Additional resources
Today we're excited to roll out a new installment in our series on Building Websites in Drupal 7 with Panels. In the continuation of this series, I will be walking you through modules and functionality provided by Panels, CTools, Page Manager, Views and more.
Drupalize.Me Free Icon Package
Blog postAre you finding yourself searching for some new icons to use on your latest project? Drupalize.Me loves helping out the Drupal community, and people in general, so for this post I thought it would be fitting to provide you with a carefully designed free icon set.
We've Launched a New Video Player
Blog postIf you've watched any videos this week you will have noticed that the video player looks very different. We've been working on this update to our entire video delivery system since the beginning of the year, and we hope you're as excited about it as we are.
Last week, we got started with the Field API. And this week, we'll continue with code-walkthrough videos for Drupal module developers who want to add field widgets, settings, and field formatters to custom fields.
Sometimes display formatters need to allow for administrators to configure additional settings. For example choosing which image style to use when displaying an image field. The Field API allows for formatter settings and we can add them by implementing hook_field_formatter_settings_summary() and hook_field_formatter_settings_form(). This lesson shows how to add simple width and height settings for the rgb_box display formatter that will allow an admin to modify the dimensions of the block that is displayed. Then uses those entered values in the implementation of hook_field_formatter_view()
added in the previous lesson to set the CSS width and height of the HTML element being displayed. Allowing site administrators a greater amount of control over what the content looks like without having to write any code. Which, also makes are module more flexible, and more useful in a larger variety of scenarios.
Field formatter settings are access via the Manage Display tab for our Article content type. Any field which provides additional settings will display a gear icon along on the far right that once clicked will reveal the settings form. Field formatter settings are per instance settings.
In addition to providing a settings form we also need to provide a simple text sumary of the settings that can be displayed on the Manage Display tab. This summary is displayed next to our field prior to someone clicking the gear icon that reveals the settings form. This gives the administrator a quick overview of the current configuration for all fields formatters. This is done with hook_field_formatter_settings_summary()
, which despite not being documented as such is required in order to provide field display formatter settings in Drupal 7.
Example:
/**
* Implements hook_field_formatter_settings_summary().
*/
function rgb_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $instance['display'][$view_mode]['settings'];
if ($display['type'] == 'rgb_box') {
$output = t('Box size: @widthx@height', array('@width' => $settings['width'], '@height' => $settings['height']));
return $output;
}
}
/**
* Implements hook_field_formatter_settings_form().
*/
function rgb_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'rgb_box') {
$element['width'] = array(
'#type' => 'textfield',
'#title' => t('Box width'),
'#default_value' => $settings['width'],
);
$element['height'] = array(
'#type' => 'textfield',
'#title' => t('Box height'),
'#default_value' => $settings['height'],
);
}
return $element;
}
Additional resources
Before our field can save user provided data we need to use hook_field_validate() and hook_field_is_empty() to perform validation on field data. In certain context values like 0, FALSE, and NULL can all be a valid value. In fact, even a blank space could be valid input for a field. As such, it's not possible for Drupal to know what constitutes an empty state for a field without a little extra help. The same is true for checking if the value of a field is valid.
Examples:
/**
* Implementation of hook_field_is_empty().
*/
function rgb_field_is_empty($item, $field) {
if (empty($item['rgb']) || empty($item['label'])) {
return TRUE;
}
return FALSE;
}
/**
* Implements hook_field_validate().
*/
function rgb_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
foreach($items as $delta => $item) {
if (!empty($item['rgb'])) {
// Make sure it's 6 characters.
if (drupal_strlen($item['rgb']) !== 6) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'rgb_length',
'message' => t('%name: the hex color must be 6 characters.', array('%name' => $instance['label'])),
);
}
}
}
}
Additional resources
Displaying that data that was collected and saved for our a field requires creating a field formatter. Formatters consist of an implementation of hook_field_formatter_info() and hook_field_formatter_view(). The former provides meta-data about the formatter for the Field API and the latter does the heavy lifting of determining what the output is actually going to look like.
A module can define more than one field formatter.
Implementations of hook_field_formatter_view()
return a renderable array representing the content you would like to display to the end user. Generally this is an escaped version of content provided by a site administrator with some additional HTML formatting applied.
Depending on the values being output you would likely want to also use a theme function for your field formatter by implementing hook_theme() and providing either a theme() function that can be overriden or a template file. We're not going to cover that in this lesson since the focus here is on the technical requirements for impelementing a field formatter. Howerver, I would say that it's best practcie to always output any HTML with a theme function. You can find out more about creating themeable output by watching these videos from our library: http://drupalize.me/videos/integrating-theme-system and http://drupalize.me/videos/using-drupal-render-api
Example:
/**
* Implements hook_field_formatter_info().
*/
function rgb_field_formatter_info() {
return array(
'rgb_raw' => array(
'label' => t('Raw color value'),
'field types' => array('rgb_color'),
),
'rgb_box' => array(
'label' => t('Color block with label'),
'field types' => array('rgb_color'),
),
);
}
/**
* Implements hook_field_formatter_view().
*/
function rgb_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, &$items, $display) {
$element = array();
switch ($display['type']) {
case 'rgb_raw':
foreach ($items as $key => $value) {
$element[$key] = array(
'#type' => 'markup',
'#markup' => t('#@hex', array('@hex' => $value['rgb'])),
);
}
break;
case 'rgb_box':
foreach ($items as $key => $value) {
$element[$key] = array(
'#type' => 'markup',
'#markup' => '' . check_plain($value['label']) . '',
);
}
break;
}
return $element;
}