first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
Context layouts
---------------
Context layouts provides a formalized way for themes to declare and switch
between page templates using Context. It is a continuation of an old Drupal
themer's trick to switch to something besides the standard `page.tpl.php` file
for a variety of special-case pages like the site frontpage, login page, admin
section, etc.
Requirements
------------
In order to use context layouts, your site must meet a few conditions:
- Context and Context layouts modules are enabled (`admin/modules`).
- You are using a theme which provides and has declared multiple layouts. (See
"Example themes" for themes you can try.)
Basic usage
-----------
Once you have layouts enabled, you can have a context trigger the usage of a
particular layout in either the admin interface (`admin/structure/context`) or
inline context editor. Different layouts may have fewer or greater regions than
the default page template, so adjust your blocks accordingly.
Supporting context layouts in your theme
----------------------------------------
You can add layouts support to your theme by declaring additional layouts in
your theme's info file. Here is an example:
`example.info`
name = "Example"
description = "Example theme"
core = "6.x"
engine = "phptemplate"
regions[left] = "Left sidebar"
regions[right] = "Right sidebar"
regions[content] = "Content"
regions[footer] = "Footer"
; Layout: Default
layouts[default][name] = "Default"
layouts[default][description] = "Simple two column page."
layouts[default][template] = "page"
layouts[default][regions][] = "content"
layouts[default][regions][] = "right"
; Layout: Columns
layouts[columns][name] = "3 columns"
layouts[columns][description] = "Three column page."
layouts[columns][stylesheet] = "layout-columns.css"
layouts[columns][template] = "layout-columns"
layouts[columns][regions][] = "left"
layouts[columns][regions][] = "content"
layouts[columns][regions][] = "right"
layouts[columns][regions][] = "footer"
Each layout is declared under `layouts` with the key as the identifier that will
be used by context for this layout. You may use any reasonable machine name for
each layout, but note that `default` is special -- it will be the default layout
for your theme if no other layout is specified.
The following keys can be declared for each layout:
- `name`: The human readable name for this layout, shown in the admin UI.
- `description`: A short description of your layout, same as above.
- `stylesheet`: A stylesheet to be included with the layout. Optional.
- `template`: The name of the template file for this layout, without the
`.tpl.php` extension.
- `region`: An array of regions supported by this layout. Note that any of the
regions listed here **must also be declared** in the standard theme `regions`
array.
Example themes
--------------
- Cube, a subtheme included with [Rubik][1] provides a variety of layouts.
- [Ginkgo][2] the default theme included with Open Atrium.
[1]: http://github.com/developmentseed/rubik/downloads
[2]: http://github.com/developmentseed/ginkgo/downloads

View File

@@ -0,0 +1,14 @@
name = Context layouts
description = Allow theme layer to provide multiple region layouts and integrate with context.
dependencies[] = context
package = Context
core = 7.x
files[] = plugins/context_layouts_reaction_block.inc
; Information added by drupal.org packaging script on 2012-12-19
version = "7.x-3.0-beta6"
core = "7.x"
project = "context"
datestamp = "1355879811"

View File

@@ -0,0 +1,130 @@
<?php
/**
* Implementation of hook_help().
*/
function context_layouts_help($path, $arg) {
switch ($path) {
case 'admin/help#context_layouts':
$output = file_get_contents(drupal_get_path('module', 'context_layouts') .'/README.txt');
return module_exists('markdown') ? filter_xss_admin(module_invoke('markdown', 'filter', 'process', 0, -1, $output)) : '<pre>'. check_plain($output) .'</pre>';
}
}
/**
* Implementation of hook_context_plugins().
* This is a ctools plugins hook.
*/
function context_layouts_context_plugins() {
return array(
'context_layouts_reaction_block' => array(
'handler' => array(
'path' => drupal_get_path('module', 'context_layouts') .'/plugins',
'file' => 'context_layouts_reaction_block.inc',
'class' => 'context_layouts_reaction_block',
'parent' => 'context_reaction_block',
),
),
);
}
/**
* Implementation of hook_context_registry_alter().
*/
function context_layouts_context_registry_alter(&$registry) {
if (isset($registry['reactions']['block'])) {
$registry['reactions']['block']['plugin'] = 'context_layouts_reaction_block';
}
}
/**
* Implementation of hook_theme().
* Declares each theme's layouts as a page template suggestion.
*/
function context_layouts_theme() {
$info = array();
foreach (list_themes() as $theme) {
if (!empty($theme->status) && $layouts = context_layouts_get_layouts($theme->name)) {
foreach ($layouts as $layout) {
if (!empty($layout['template'])) {
$info["page__context_layouts_{$theme->name}_{$layout['layout']}"] = array(
'template' => $layout['template'],
'path' => drupal_get_path('theme', $theme->name),
);
}
}
}
}
return $info;
}
/**
* Implementation of hook_context_page_reaction().
*/
function context_layouts_context_page_reaction() {
$plugin = context_get_plugin('reaction', 'block');
if ($plugin && method_exists($plugin, 'add_layout_stylesheet')) {
$plugin->add_layout_stylesheet();
}
}
/**
* Preprocessor for theme('page').
*/
function context_layouts_preprocess_page(&$vars) {
$plugin = context_get_plugin('reaction', 'block');
if ($plugin && method_exists($plugin, 'add_layout_template')) {
$plugin->add_layout_template($vars);
}
}
/**
* Retrieve layouts for the specified theme.
*/
function context_layouts_get_layouts($theme = NULL, $reset = FALSE) {
static $layouts = array();
$layouts = $reset ? array() : $layouts;
global $theme_key;
$theme = isset($theme) ? $theme : $theme_key;
if (!isset($layouts[$theme])) {
$info = system_get_info('theme', $theme);
$themes = array();
// Find all our ancestor themes that use layouts.
if (isset($info['base theme'])) {
while (!empty($info['base theme'])) {
$base_theme = $info['base theme'];
$info = system_get_info('theme', $base_theme);
$themes[$base_theme] = $info;
}
}
// Assemble in inheritance order and add the theme on.
$themes = array_reverse($themes);
$themes[$theme] = system_get_info('theme', $theme);
// Merge layout info into a single array.
foreach ($themes as $key => $info) {
if (!empty($info['layouts'])) {
foreach ($info['layouts'] as $layout => $layout_info) {
$layout_info['layout'] = str_replace('-', '_', $layout);
$layout_info['theme'] = $key;
$layouts[$theme][$layout] = $layout_info;
}
}
}
}
return isset($layouts[$theme]) ? $layouts[$theme] : FALSE;
}
/**
* Get the active layout for the current page.
*/
function context_layouts_get_active_layout($info = TRUE) {
$plugin = context_get_plugin('reaction', 'block');
if ($plugin && method_exists($plugin, 'get_active_layout')) {
return $plugin->get_active_layout($info);
}
}

View File

@@ -0,0 +1,8 @@
#admin-toolbar div.context-editor-block-layouts {
padding:0px 0px 9px;
border-bottom:1px solid #333;
margin:0px 0px 10px;
}
#admin-toolbar div.context-editor-block-layouts div.form-item { display:inline; }
#admin-toolbar div.context-editor-block-layouts select { width:50%; }

View File

@@ -0,0 +1,205 @@
<?php
class context_layouts_reaction_block extends context_reaction_block {
/**
* Override of is_enabled_region().
* Check that there is an active layout and it supports the given region.
*/
protected function is_enabled_region($region) {
$layout = $this->get_active_layout();
if ($layout && isset($layout['regions']) && is_array($layout['regions'])) {
return in_array($region, $layout['regions'], TRUE) && parent::is_enabled_region($region);
}
return parent::is_enabled_region($region);
}
/**
* Retrieve the first layout specified found by any active contexts.
*/
function get_active_layout($info = TRUE) {
$contexts = $this->get_contexts();
$layouts = context_layouts_get_layouts();
if (!empty($contexts) && !empty($layouts)) {
foreach ($contexts as $context) {
$values = $this->fetch_from_context($context);
if (isset($values['layout']) && isset($layouts[$values['layout']])) {
return $info ? $layouts[$values['layout']] : $values['layout'];
}
}
}
// Fallback to default layout if provided.
if (isset($layouts['default'])) {
return $info ? $layouts['default'] : 'default';
}
return FALSE;
}
/**
* Add the layout template to page vars.
*/
function add_layout_template(&$vars) {
if ($layout = $this->get_active_layout()) {
if (!empty($layout['template'])) {
global $theme;
$vars['theme_hook_suggestion'] = "page__context_layouts_{$theme}_{$layout['layout']}";
}
}
}
/**
* Add the layout stylesheet to the CSS.
*/
function add_layout_stylesheet() {
if ($layout = $this->get_active_layout()) {
if (!empty($layout['stylesheet'])) {
drupal_add_css(drupal_get_path('theme', $layout['theme']) . '/' . $layout['stylesheet']);
}
}
}
/**
* Override of editor form.
*/
function editor_form($context) {
drupal_add_css(drupal_get_path('module', 'context_layouts') . '/plugins/context_layouts_reaction_block.css');
$form = parent::editor_form($context);
if ($layouts = $this->get_layout_options()) {
$options = $this->fetch_from_context($context);
$form['layout'] = array(
// #tree *must* be true for our values to be nested correctly.
'#tree' => TRUE,
'#prefix' => '<div class="context-editor-block-layouts">',
'#suffix' => '</div>',
'#weight' => -100,
'layout' => array(
'#title' => t('Layout'),
'#options' => $layouts,
'#type' => 'select',
'#weight' => -100,
'#default_value' => isset($options['layout']) ? $options['layout'] : NULL,
'#required' => FALSE,
'#empty_value' => 0,
'#empty_option' => '- ' . t('Site default') . ' -',
),
'update' => array(
'#value' => t('Change layout'),
'#type' => 'submit',
),
);
}
return $form;
}
/**
* Override of editor form submit.
*/
function editor_form_submit(&$context, $values) {
// Someone has changed the layout, assume that the block values are not actually usable here.
if (isset($context->reactions['block']['layout']) && $context->reactions['block']['layout'] != $values['layout']['layout']) {
$options = $context->reactions['block'];
}
else {
$options = parent::editor_form_submit($context, $values);
}
if (!empty($values['layout']['layout'])) {
$options['layout'] = $values['layout']['layout'];
}
else {
unset($options['layout']);
}
return $options;
}
/**
* Override of options form.
*/
function options_form($context) {
$form = parent::options_form($context);
$options = $this->fetch_from_context($context);
// Only alter the options form if the theme provides layouts.
$theme_key = variable_get('theme_default', 'garland');
$layouts = $this->get_layout_options();
if (!empty($layouts)) {
$form['layout'] = array(
'#title' => t('Layout'),
'#description' => t('Choose one of the layouts provided by the default theme.'),
'#options' => $layouts,
'#type' => 'select',
'#weight' => -100,
'#default_value' => !empty($options['layout']) ? $options['layout'] : NULL,
'#attributes' => array('class' => array('context-blockform-layout')),
'#required' => FALSE,
'#empty_value' => 0,
'#empty_option' => '- ' . t('Site default') . ' -',
);
// Add js.
// @TODO: Move this to a theme function or somewhere that will get called even
// if the form is using a cached version of itself (e.g. when validate fails).
drupal_add_js(drupal_get_path('module', 'context_layouts') . '/plugins/context_layouts_reaction_block.js');
drupal_add_js(array('contextLayouts' => array('layouts' => $this->get_layout_regions())), 'setting');
}
return $form;
}
/**
* Override of submit handler.
*/
function options_form_submit($values) {
$options = parent::options_form_submit($values);
// Only alter the options form if the theme provides layouts.
$theme_key = variable_get('theme_default', 'garland');
$layouts = context_layouts_get_layouts($theme_key);
// Check that this is a valid layout.
if (!empty($values['layout']) && isset($layouts[$values['layout']])) {
$layout = $values['layout'];
$options['layout'] = $layout;
// Remove blocks that don't belong to regions in this layout.
if (isset($layouts[$layout]['regions'])) {
foreach ($options['blocks'] as $bid => $block) {
if (!in_array($block['region'], $layouts[$layout]['regions'])) {
unset($options['blocks'][$bid]);
}
}
}
}
return $options;
}
/**
* Get layout options for the given theme.
*/
protected function get_layout_options($theme_key = NULL) {
$theme_key = !isset($theme_key) ? variable_get('theme_default', 'garland') : $theme_key;
$layouts = context_layouts_get_layouts($theme_key);
$layout_options = array();
if (!empty($layouts)) {
foreach ($layouts as $layout => $info) {
$layout_options[$layout] = isset($info['name']) ? $info['name'] : $layout_options;
}
}
return $layout_options;
}
/**
* Get a layout to region map for the given theme.
*/
protected function get_layout_regions($theme_key = NULL) {
$theme_key = !isset($theme_key) ? variable_get('theme_default', 'garland') : $theme_key;
$layouts = context_layouts_get_layouts($theme_key);
if (!empty($layouts)) {
$layout_regions = array();
foreach ($layouts as $layout => $info) {
$layout_regions[$layout] = is_array($info['regions']) ? $info['regions'] : array();
}
}
return $layout_regions;
}
}

View File

@@ -0,0 +1,27 @@
(function($) {
Drupal.behaviors.contextLayoutsReactionBlock = {};
Drupal.behaviors.contextLayoutsReactionBlock.attach = function(context) {
// ContextBlockForm: Init.
$('.context-blockform-layout:not(.contextLayoutsProcessed)').each(function() {
$(this).addClass('contextLayoutsProcessed');
$(this).change(function() {
var layout = $(this).val();
if (Drupal.settings.contextLayouts.layouts[layout]) {
$('#context-blockform td.blocks').find('table, div.label, div.tabledrag-toggle-weight-wrapper').hide();
for (var key in Drupal.settings.contextLayouts.layouts[layout]) {
var region = Drupal.settings.contextLayouts.layouts[layout][key];
$('.context-blockform-regionlabel-'+region).show().next('div.tabledrag-toggle-weight-wrapper').show();
$('#context-blockform-region-'+region).show();
}
if (Drupal.contextBlockForm) {
Drupal.contextBlockForm.setState();
}
}
});
$(this).change();
});
};
})(jQuery);