diff --git a/core/modules/layout/layout.admin.css b/core/modules/layout/layout.admin.css new file mode 100644 index 0000000000000000000000000000000000000000..6e38bf48d8af47ab2798e4cb8d8f9ac423de6e26 --- /dev/null +++ b/core/modules/layout/layout.admin.css @@ -0,0 +1,17 @@ +.layout-display { + background: rgb(224, 224, 224); +} + +.layout-region-demonstration { + background-image: -moz-linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%); + background-image: -o-linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%); + background-image: -ms-linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%); + background-image: -webkit-linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%); + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.4, rgb(70,70,71)), color-stop(0.7, rgb(91,91,94)), color-stop(0.88, rgb(125,124,125))); + background-image: linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%); + color: white; + font-size: 0.8em; + margin: 3px; + padding: 10px; + text-transform: uppercase; +} diff --git a/core/modules/layout/layout.admin.inc b/core/modules/layout/layout.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..9a1a9213d72068bfce85f081ac04faf0c80bcee3 --- /dev/null +++ b/core/modules/layout/layout.admin.inc @@ -0,0 +1,75 @@ +getDefinitions(); + + $rows = array(); + $header = array(t('Name'), t('Source')); + foreach ($layouts as $name => $layout) { + $provider_info = system_get_info($layout['provider']['type'], $layout['provider']['provider']); + + // Build table columns for this row. + $row = array(); + $row['name'] = l($layout['title'], 'admin/structure/templates/manage/' . $name); + // Type can either be 'module' or 'theme'. + $row['provider'] = t('@name @type', array('@name' => $provider_info['name'], '@type' => t($layout['provider']['type']))); + + $rows[] = $row; + } + + $build = array(); + $build['table'] = array( + '#theme' => 'table', + '#header' => $header, + '#rows' => $rows, + ); + return $build; + + // Ensure the provider types are translatable. These do not need to run, + // just inform the static code parser of these source strings. + t('module'); + t('theme'); +} + +/** + * Page callback: Demonstrates a layout template. + * + * @param string $key + * The key of the page layout being requested. + * + * @return array + * An array as expected by drupal_render(). + * + * @see layout_menu() + */ +function layout_page_view($key) { + $layout = layout_manager()->getDefinition($key); + drupal_set_title(t('View template %name', array('%name' => $layout['title'])), PASS_THROUGH); + + // Render the layout in an admin context with region demonstrations. + $instance = layout_manager()->createInstance($key, array()); + $regions = $instance->getRegions(); + foreach ($regions as $region => $info) { + $regions[$region] = '
' . check_plain($info['label']) . '
'; + } + $build['demonstration'] = array( + '#type' => 'markup', + '#markup' => $instance->renderLayout(TRUE, $regions), + ); + $build['#attached']['css'][] = drupal_get_path('module', 'layout') . '/layout.admin.css'; + return $build; +} diff --git a/core/modules/layout/layout.module b/core/modules/layout/layout.module index 7d8279826c956bb64be345832fa1f0281bba6f75..c6ed7ae5612d76c987eebb4aadd5c95c7790e344 100644 --- a/core/modules/layout/layout.module +++ b/core/modules/layout/layout.module @@ -5,6 +5,55 @@ * Manages page layouts for content presentation. */ +/** + * Implements hook_menu(). + */ +function layout_menu() { + $items['admin/structure/templates'] = array( + 'title' => 'Templates', + 'description' => 'Overview of the list of layout templates available.', + 'page callback' => 'layout_page_list', + 'access callback' => 'user_access', + 'access arguments' => array('administer layouts'), + 'file' => 'layout.admin.inc', + ); + $items['admin/structure/templates/manage/%'] = array( + 'title' => 'View template', + 'page callback' => 'layout_page_view', + 'page arguments' => array(4), + 'access callback' => 'layout_user_access', + 'access arguments' => array(4), + 'file' => 'layout.admin.inc', + ); + return $items; +} + +/** + * Access callback: Checks the existence of a layout. + * + * @param string $key + * The key of the page layout being requested. + * + * @return bool + * TRUE if the current user can access page layout menu items; FALSE + * otherwise. + */ +function layout_user_access($key) { + return (user_access('administer layouts') && layout_manager()->getDefinition($key)); +} + +/** + * Implements hook_permission(). + */ +function layout_permission() { + return array( + 'administer layouts' => array( + 'title' => t('Administer templates'), + 'description' => t('Access administration functions for templates.'), + ), + ); +} + /** * Get the layout plugin manager instance. * diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php b/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php index ce82c655a3113124b22ebe57751870e7d09da5a1..a6c4ea947dfe5b077aaa055b034e76c3defc54fc 100644 --- a/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php +++ b/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php @@ -106,6 +106,7 @@ protected function iterateDirectories($dir, $provider) { $this->derivatives[$key] = $directory->read($fileinfo->getBasename('.yml')); $this->derivatives[$key]['theme'] = $key; $this->derivatives[$key]['path'] = $fileinfo->getPath(); + $this->derivatives[$key]['provider'] = $provider; // If the layout author didn't specify a template name, assume the same // name as the yml file. if (!isset($this->derivatives[$key]['template'])) { diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php index 7521c57f9c3f6821b25862cfc4b96cf26ea6162d..829f3c204105c507ddb94d421acf3849f1b4bcb6 100644 --- a/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php +++ b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php @@ -18,15 +18,25 @@ interface LayoutInterface extends PluginInspectionInterface { * Returns a list of regions. * * @return array - * An array of region machine names. + * An associative array of region information keyed by region machine + * names. Each region information element is a two item associative array + * with a 'label' and a 'type' key designating the human readable label + * and the type of the region. */ public function getRegions(); /** * Renders layout and returns the rendered markup. * + * @param bool $admin + * (optional) TRUE if the rendered layout is displayed in an administrative + * context, FALSE otherwise. Defaults to FALSE. + * @param array $regions + * (optional) An array of region render arrays keyed by region machine + * names. Defaults to array. + * * @return string * Rendered HTML output from the layout. */ - public function renderLayout(); + public function renderLayout($admin = FALSE, $regions = array()); } diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/StaticLayout.php b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/StaticLayout.php index 3ded37918d1ba9a9acbb0c1a8b58e6caadfb5636..f3f6762ed315adf762adc8933b596f45c2862a4d 100644 --- a/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/StaticLayout.php +++ b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/StaticLayout.php @@ -78,7 +78,7 @@ public function getAdminScriptFiles() { /** * Implements Drupal\layout\Plugin\LayoutInterface::renderLayout(). */ - public function renderLayout($admin = FALSE) { + public function renderLayout($admin = FALSE, $regions = array()) { $definition = $this->getDefinition(); // Assemble a render array with the regions and attached CSS/JS. @@ -89,10 +89,8 @@ public function renderLayout($admin = FALSE) { // Render all regions needed for this layout. foreach ($this->getRegions() as $region => $info) { - // @todo This is just stub code to fill in regions with stuff for now. - // When blocks are related to layouts and not themes, we can make this - // really be filled in with blocks. - $build['#content'][$region] = '

' . $info['label'] . '

'; + // Initialize regions which were not provided as empty. + $build['#content'][$region] = empty($regions[$region]) ? '' : $regions[$region]; } // Fill in attached CSS and JS files based on metadata. diff --git a/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.php b/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.php index 0766838d3e7fda4ca6af826e37ce239772cb5caf..f41460cb2ffd0452cf279d463aea844faecbed27 100644 --- a/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.php +++ b/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.php @@ -52,7 +52,7 @@ function testDerivatives() { // Render the layout and look at whether expected region names and classes // were in the output. - $render = $layout->renderLayout(); + $render = $this->renderLayoutDemonstration($layout); $this->drupalSetContent($render); $this->assertText('Middle column'); $this->assertRaw('class="layout-display layout-one-col'); @@ -68,13 +68,32 @@ function testDerivatives() { // Render the layout and look at whether expected region names and classes // were in the output. - $render = $layout->renderLayout(); + $render = $this->renderLayoutDemonstration($layout); $this->drupalSetContent($render); $this->assertText('Left side'); $this->assertText('Right side'); $this->assertRaw('
'); } + /** + * Renders the layout with sample region content. + * + * @param \Drupal\layout\Plugin\LayoutInterface $layout + * The layout to be rendered. + * + * @return string + * Rendered HTML output from the layout. + */ + function renderLayoutDemonstration($layout) { + // Add sample content in the regions that is looked for in the tests. + $regions = $layout->getRegions(); + foreach ($regions as $region => $info) { + $regions[$region] = '

' . $info['label'] . '

'; + } + + return $layout->renderLayout(FALSE, $regions); + } + /** * Test layout functionality as applies to pages. */ diff --git a/core/modules/layout/tests/layout_test.module b/core/modules/layout/tests/layout_test.module index b9eb63be451d381bc05b9f594d1fe9820637f7b1..74de123e905c04c703b41f660e7dad17ff3e5890 100644 --- a/core/modules/layout/tests/layout_test.module +++ b/core/modules/layout/tests/layout_test.module @@ -27,11 +27,19 @@ function layout_test_page() { global $theme; $theme = 'layout_test_theme'; theme_enable(array($theme)); + $display = entity_load('display', 'test_twocol'); $layout = $display->getLayoutInstance(); + // @todo This tests that the layout can render its regions, but does not test // block rendering: http://drupal.org/node/1812720. - return $layout->renderLayout(); + // Add sample content in the regions that is looked for in the tests. + $regions = $layout->getRegions(); + foreach ($regions as $region => $info) { + $regions[$region] = '

' . $info['label'] . '

'; + } + + return $layout->renderLayout(FALSE, $regions); } /**