layout.module in Layout 7
Same filename and directory in other branches
Responsive layout builder tool for Panels.
File
layout.moduleView source
<?php
/**
* @file
* Responsive layout builder tool for Panels.
*/
/**
* Implementation of hook_module_implements_alter().
*/
function layout_module_implements_alter(&$implementations, $hook) {
if ($hook == 'menu_alter') {
// Move layout_menu_alter() to the end of the list. module_implements()
// iterates through $implementations with a foreach loop which PHP iterates
// in the order that the items were added, so to move an item to the end of
// the array, we remove it and then add it.
$group = $implementations['layout'];
unset($implementations['layout']);
$implementations['layout'] = $group;
}
}
/**
* Implementation of hook_menu_alter().
*/
function layout_menu_alter(&$items) {
// Convert the automatically created ctools menu items to local tasks.
if (isset($items['admin/structure/panels/layouts/breakpoints'])) {
$items['admin/structure/panels/layouts/breakpoints']['type'] = MENU_LOCAL_TASK;
}
if (isset($items['admin/structure/panels/layouts/regions'])) {
$items['admin/structure/panels/layouts/regions']['type'] = MENU_LOCAL_TASK;
}
// Hide this local action so its not visible anymore in Panels.
if (isset($items['admin/structure/panels/layouts/add-flexible'])) {
$items['admin/structure/panels/layouts/add-flexible']['type'] = MENU_CALLBACK;
$items['admin/structure/panels/layouts/add-responsive']['title'] = 'Add layout';
// Modify the title on the 'List' tab, although this makes it pretty
// non-standard, by putting more things on the same level (breakpoints,
// grids and regions by side of layouts), it becomes confusing as long
// as the tab is labeled 'List'.
$items['admin/structure/panels/layouts/list']['title'] = 'Layouts';
}
}
/**
* Implements hook_permission().
*/
function layout_permission() {
return array(
'administer layouts' => array(
'title' => t('Administer responsive layouts'),
'description' => t('Administer backend settings for responsive layouts.'),
),
);
}
/**
* Implements hook_ctools_plugin_directory().
*/
function layout_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'panels' && $plugin_type == 'layouts' || $owner == 'ctools' && $plugin_type == 'export_ui') {
return "plugins/{$plugin_type}";
}
}
/**
* Implementation of hook_ctools_plugin_api().
*
* Tell CTools that we support the default_layout_breakpoint and
* default_panels_layout APIs.
*/
function layout_ctools_plugin_api($owner, $api) {
if ($owner == 'layout' && $api == 'default_layout_breakpoint' || $owner == 'layout' && $api == 'default_layout_region' || $owner == 'panels' && $api == 'layouts') {
return array(
'version' => 1,
);
}
}
// == Layouts =================================================================
/**
* Implementation of hook_default_panels_layout().
*
* Provide a couple default layouts.
*/
function layout_default_panels_layout() {
$export = array();
$layout = new stdClass();
$layout->disabled = FALSE;
$layout->api_version = 1;
$layout->name = 'default';
$layout->admin_title = 'Default responsive layout';
$layout->admin_description = '';
$layout->category = '';
$layout->plugin = 'responsive';
$layout->settings = array(
'regions' => array(
'header_a' => 'header_a',
'header_b' => 'header_b',
'header_c' => 'header_c',
'subheader_a' => 'subheader_a',
'subheader_b' => 'subheader_b',
'subheader_c' => 'subheader_c',
'navigation' => 'navigation',
'title' => 'title',
'body' => 'body',
'sidebar_a' => 'sidebar_a',
'sidebar_b' => 'sidebar_b',
'sidebar_c' => 'sidebar_c',
'footer_a' => 'footer_a',
'footer_b' => 'footer_b',
'footer_c' => 'footer_c',
),
'overrides' => array(),
);
$export['default'] = $layout;
return $export;
}
// == Regions =================================================================
/**
* Implementation of hook_default_layout_region().
*
* Provide a couple of default regions.
*/
function layout_default_layout_region() {
$export = array();
$base_regions = array(
'header_a' => 'Header A',
'header_b' => 'Header B',
'header_c' => 'Header C',
'subheader_a' => 'Subheader A',
'subheader_b' => 'Subheader B',
'subheader_c' => 'Subheader C',
'navigation' => 'Navigation',
'title' => 'Title',
'body' => 'Body',
'sidebar_a' => 'Sidebar A',
'sidebar_b' => 'Sidebar B',
'sidebar_c' => 'Sidebar C',
'footer_a' => 'Footer A',
'footer_b' => 'Footer B',
'footer_c' => 'Footer C',
);
foreach ($base_regions as $name => $admin_title) {
$region = new stdClass();
$region->api_version = 1;
$region->name = $name;
$region->admin_title = $admin_title;
$export[$name] = $region;
}
return $export;
}
/**
* Add or update region in common set of regions.
*
* @param $region
* A fully populated region object.
*/
function layout_region_save($region) {
ctools_include('export');
$regions = ctools_export_crud_save('layout_region', $region);
return $regions;
}
/**
* Load all common layout regions.
*
* @return
* All common regions in an associative array keyed by machine name.
*/
function layout_region_load_all() {
ctools_include('export');
$regions = ctools_export_crud_load_all('layout_region');
return $regions;
}
/**
* Load one layout based on its machine name.
*/
function layout_region_load($name) {
ctools_include('export');
return ctools_export_crud_load('layout_region', $name);
}
/**
* Get a list of layout names using the given region machine name.
*/
function layout_get_layouts_using_region($name) {
$layouts = layout_get_responsive_layouts();
$layouts_using_region = array();
foreach ($layouts as $data) {
if (isset($data['layout']->settings['regions']) && is_array($data['layout']->settings['regions']) && isset($data['layout']->settings['regions'][$name])) {
$layouts_using_region[$data['layout']->name] = $data['title'];
}
}
return $layouts_using_region;
}
// == Breakpoints =============================================================
/**
* Implementation of hook_default_layout_breakpoint().
*
* Provide a couple of default breakpoints.
*/
function layout_default_layout_breakpoint() {
$export = array();
$breakpoint = new stdClass();
$breakpoint->api_version = 1;
$breakpoint->name = 'smartphone';
$breakpoint->admin_title = 'Smartphone';
$breakpoint->width = '0px';
$breakpoint->grid_name = 'three_column_fluid';
$export['smatphone'] = $breakpoint;
$breakpoint = new stdClass();
$breakpoint->api_version = 1;
$breakpoint->name = 'tablet';
$breakpoint->admin_title = 'Tablet';
$breakpoint->width = '320px';
$breakpoint->grid_name = 'six_column_fluid';
$export['tablet'] = $breakpoint;
$breakpoint = new stdClass();
$breakpoint->api_version = 1;
$breakpoint->name = 'standard';
$breakpoint->admin_title = 'Standard';
$breakpoint->width = '760px';
$breakpoint->grid_name = 'twelve_column_fluid';
$export['standard'] = $breakpoint;
return $export;
}
/**
* API function to get all responsive breakpoint on the site.
*/
function layout_breakpoint_load_all() {
ctools_include('export');
$breakpoints = ctools_export_crud_load_all('layout_breakpoint');
uasort($breakpoints, 'layout_breakpoint_sort_by_width');
return $breakpoints;
}
/**
* Look up one breakpoint setup based on machine name.
*/
function layout_breakpoint_load($name) {
ctools_include('export');
return ctools_export_crud_load('layout_breakpoint', $name);
}
/**
* Build CSS for the breakpoints with media queries.
*
* @param boolean $include_media_queries
* Whether generate one flat CSS without media queries (useful for
* administration), or wrap breakpoints with media queries (for frontend).
*
* @todo
* Figure out a good way to avoid equal max/min-weights in subsequent
* breakpoints if that is a problem.
*/
function layout_breakpoint_get_css($include_media_queries = TRUE) {
$breakpoints = layout_breakpoint_load_all();
$breakpoint_css = array();
$min_width = 0;
$breakpoint_count = count($breakpoints);
$breakpoint_index = 0;
foreach ($breakpoints as $name => $breakpoint) {
if ($include_media_queries) {
// Build the media query for this breakpoint. The first item should have a
// min-width of 0, and the last item should have no max-width
// (open-ended to infinity). Mid-items should both have a min-width and a
// max-width. A breakpoint specifies the max-width for the previous breakpoint
// (if any).
$breakpoint_css[$breakpoint_index]['media-query'] = '@media screen and (min-width:' . $breakpoint->width . ')';
if ($breakpoint_index > 0) {
$breakpoint_css[$breakpoint_index - 1]['media-query'] .= ' and (max-width: ' . $breakpoint->width . ')';
}
// Get grid CSS from gridbuilder and apply some extra indentation.
$breakpoint_css[$breakpoint_index]['css'] = ' ' . str_replace("\n", "\n ", gridbuilder_get_css($breakpoint->grid_name, '.panel-responsive', '.rld-span-' . $name . '_'));
$breakpoint_index++;
}
else {
$breakpoint_css[$breakpoint_index]['css'] = gridbuilder_get_css($breakpoint->grid_name, NULL, NULL, TRUE);
}
}
// Build CSS based on media query information.
$built_css = '';
foreach ($breakpoint_css as $data) {
if (isset($data['media-query'])) {
$built_css .= $data['media-query'] . " {\n" . $data['css'] . "\n}";
}
else {
$built_css .= $data['css'] . "\n";
}
}
return $built_css;
}
/**
* Sort the breakpoints in ascending order by their width.
*/
function layout_breakpoint_sort_by_width($a, $b) {
// Cast the width to int. Whether it provided as px or em, the cast should
// result in a relevant number. It will not sort mixed em/px numbers properly
// but that sounds like a broken setup. Not desigining for that.
if ((int) $a->width == (int) $b->width) {
return 0;
}
return (int) $a->width < (int) $b->width ? -1 : 1;
}
// == Layouts =================================================================
/**
* Get all responsive layout info arrays from panels.
*/
function layout_get_responsive_layouts() {
ctools_include('plugins', 'panels');
$all_layouts = panels_get_layouts();
$responsive_layouts = array();
foreach ($all_layouts as $name => $data) {
if (empty($data['builder']) && isset($data['layout']->plugin) && $data['layout']->plugin == 'responsive') {
$responsive_layouts[$name] = $data;
}
}
return $responsive_layouts;
}
Functions
Name | Description |
---|---|
layout_breakpoint_get_css | Build CSS for the breakpoints with media queries. |
layout_breakpoint_load | Look up one breakpoint setup based on machine name. |
layout_breakpoint_load_all | API function to get all responsive breakpoint on the site. |
layout_breakpoint_sort_by_width | Sort the breakpoints in ascending order by their width. |
layout_ctools_plugin_api | Implementation of hook_ctools_plugin_api(). |
layout_ctools_plugin_directory | Implements hook_ctools_plugin_directory(). |
layout_default_layout_breakpoint | Implementation of hook_default_layout_breakpoint(). |
layout_default_layout_region | Implementation of hook_default_layout_region(). |
layout_default_panels_layout | Implementation of hook_default_panels_layout(). |
layout_get_layouts_using_region | Get a list of layout names using the given region machine name. |
layout_get_responsive_layouts | Get all responsive layout info arrays from panels. |
layout_menu_alter | Implementation of hook_menu_alter(). |
layout_module_implements_alter | Implementation of hook_module_implements_alter(). |
layout_permission | Implements hook_permission(). |
layout_region_load | Load one layout based on its machine name. |
layout_region_load_all | Load all common layout regions. |
layout_region_save | Add or update region in common set of regions. |