diff --git a/core/modules/layout/layout.info b/core/modules/layout/layout.info new file mode 100644 index 0000000..187bfea --- /dev/null +++ b/core/modules/layout/layout.info @@ -0,0 +1,5 @@ +name = Layout +description = Makes it possible to swap different page layouts. +package = Core +version = VERSION +core = 8.x diff --git a/core/modules/layout/layout.module b/core/modules/layout/layout.module new file mode 100644 index 0000000..7b0ab2c --- /dev/null +++ b/core/modules/layout/layout.module @@ -0,0 +1,39 @@ +renderLayout(). + */ +function layout_page_build(&$page) { + $request = drupal_container()->get('request'); + $options = array( + 'request' => $request, + ); + $layout = layout_manager()->getInstance($options); + if ($layout) { + $page['#children'] = $layout->renderLayout(); + $page['#theme'] = NULL; + } +} + +/** + * Get the layout plugin manager instance. + * + * @return Drupal\layout\Plugin\Type\LayoutManager + * The layout plugin manager instance. + */ +function layout_manager() { + return drupal_container()->get('plugin.manager.layout'); +} diff --git a/core/modules/layout/layout/onecol/layout--onecol.tpl.php b/core/modules/layout/layout/onecol/layout--onecol.tpl.php new file mode 100644 index 0000000..27eefa9 --- /dev/null +++ b/core/modules/layout/layout/onecol/layout--onecol.tpl.php @@ -0,0 +1,19 @@ + +
> +
+
+
+
diff --git a/core/modules/layout/layout/onecol/onecol.css b/core/modules/layout/layout/onecol/onecol.css new file mode 100644 index 0000000..9515b54 --- /dev/null +++ b/core/modules/layout/layout/onecol/onecol.css @@ -0,0 +1,22 @@ + +.layout-1col { +/* overflow: hidden; */ +} + +.layout-2col .layout-col-first .inside { + margin: 0; +} + + +.layout-1col .layout-col { + width: 100%; +} + +#layout-edit-display .layout-region, +#layout-edit-display .helperclass { + margin: .5em; +} + +.layout-2col .layout-separator { + margin: 0 0 1em 0; +} diff --git a/core/modules/layout/layout/onecol/onecol.yml b/core/modules/layout/layout/onecol/onecol.yml new file mode 100644 index 0000000..2ad8959 --- /dev/null +++ b/core/modules/layout/layout/onecol/onecol.yml @@ -0,0 +1,6 @@ +title: Single column +category: Columns: 1 +icon: onecol.png +css: onecol.css +regions: + middle: 'Middle column' diff --git a/core/modules/layout/layout/twocol/layout--twocol.tpl.php b/core/modules/layout/layout/twocol/layout--twocol.tpl.php new file mode 100644 index 0000000..90a69af --- /dev/null +++ b/core/modules/layout/layout/twocol/layout--twocol.tpl.php @@ -0,0 +1,25 @@ + +
> +
+
+
+ +
+
+
+
diff --git a/core/modules/layout/layout/twocol/twocol.css b/core/modules/layout/layout/twocol/twocol.css new file mode 100644 index 0000000..ecbd867 --- /dev/null +++ b/core/modules/layout/layout/twocol/twocol.css @@ -0,0 +1,37 @@ + +.layout-2col { +/* overflow: hidden; */ +} + +.layout-2col .layout-col-first { + float: left; + width: 50%; +} +* html .layout-2col .layout-col-first { + width: 49.9%; +} + +.layout-2col .layout-col-first .inside { + margin: 0 .5em 1em 0; +} + +.layout-2col .layout-col-last { + float: left; + width: 50%; +} +* html .layout-2col .layout-col-last { + width: 49.9%; +} + +.layout-2col .layout-col-last .inside { + margin: 0 0 1em .5em; +} + +#layout-edit-display .layout-region, +#layout-edit-display .helperclass { + margin: .5em; +} + +.layout-2col .layout-separator { + margin: 0 0 1em 0; +} diff --git a/core/modules/layout/layout/twocol/twocol.yml b/core/modules/layout/layout/twocol/twocol.yml new file mode 100644 index 0000000..90c4a3e --- /dev/null +++ b/core/modules/layout/layout/twocol/twocol.yml @@ -0,0 +1,7 @@ +title: Two column +category: Columns: 2 +icon: twocol.png +css: twocol.css +regions: + left: 'Left side' + right: 'Right side' diff --git a/core/modules/layout/lib/Drupal/layout/LayoutBundle.php b/core/modules/layout/lib/Drupal/layout/LayoutBundle.php new file mode 100644 index 0000000..92b4796 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/LayoutBundle.php @@ -0,0 +1,24 @@ +register('plugin.manager.layout', 'Drupal\layout\Plugin\Type\LayoutManager'); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php b/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php new file mode 100644 index 0000000..f7a9146 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php @@ -0,0 +1,74 @@ +derivatives) && !empty($this->derivatives[$derivative_id])) { + return $this->derivatives[$derivative_id]; + } + $this->getDerivativeDefinitions($base_plugin_definition); + return $this->derivatives[$derivative_id]; + } + + /** + * Implements DerivativeInterface::getDerivativeDefinitions(). + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + $available_layout_providers = array(); + foreach (module_list() as $module) { + $available_layout_providers[$module] = array( + 'type' => 'module', + 'provider' => $module, + 'dir' => drupal_get_path('module', $module), + ); + } + foreach (list_themes() as $theme_id => $theme) { + $available_layout_providers[$theme_id] = array( + 'type' => 'theme', + 'provider' => $theme->name, + 'dir' => drupal_get_path('theme', $theme->name), + ); + } + foreach ($available_layout_providers as $provider) { + $dir = $provider['dir'] . DIRECTORY_SEPARATOR . 'layout'; + // If the directory structure exists, look for layouts. + if (file_exists($dir)) { + $this->iterateDirectories($dir, $provider); + } + } + return $this->derivatives; + } + + /** + * Finds layout definitions by looking for layout metadata. + */ + protected function iterateDirectories($dir, $provider) { + $directories = new DirectoryIterator($dir); + foreach ($directories as $fileinfo) { + if ($fileinfo->isDir() && !$fileinfo->isDot()) { + $this->iterateDirectories($fileinfo->getPathname(), $provider); + } + elseif ($fileinfo->isFile() && $fileinfo->getExtension() == 'yml') { + $directory = new FileStorage($fileinfo->getPath()); + $this->derivatives[$provider['provider'] . '__' . $fileinfo->getBasename('.yml')] = $directory->read($fileinfo->getBasename('.yml')); + $this->derivatives[$provider['provider'] . '__' . $fileinfo->getBasename('.yml')]['template'] = $provider['provider'] . '--' . $fileinfo->getBasename('.yml'); + $this->derivatives[$provider['provider'] . '__' . $fileinfo->getBasename('.yml')]['path'] = $fileinfo->getPath(); + } + } + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php new file mode 100644 index 0000000..0863a67 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php @@ -0,0 +1,27 @@ +manager = $manager; + } + + /** + * Implements MapperInterface::getInstance(). + */ + public function getInstance(array $options) { + if (empty($options['request']) || !$options['request'] instanceof Request) { + // Throw an exception. + } + // Find all modules that respond with a layout for the current request and + // sort them by weight and take the first one in the list. + if ($layouts = module_invoke_all('layout', $options['request'])) { + usort($layouts, array($this, 'sort')); + $layout = array_shift($layouts); + return $this->manager->createInstance($layout['layout'], $layout); + } + // If no modules responded for the current request, then fallback to the + // default that the block administration page represents. + else { + global $theme; + if ($theme != 'bartik') { + return; + } + $conf = array(); + $blocks = array(); + $block_configs = config_get_storage_names_with_prefix('plugin.core.block.' . $theme); + foreach ($block_configs as $config) { + $blocks[$config] = config($config)->get(); + if (empty($blocks[$config]['config_id'])) { + $blocks[$config]['config_id'] = $config; + } + } + usort($blocks, array($this, 'sort')); + foreach ($blocks as $config) { + $conf['regions'][$config['region']][$config['config_id']] = array(); + } + return $this->manager->createInstance('default_layout:bartik__bartik', $conf); + } + } + + function sort($a, $b) { + // Sort by weight. + $weight = $a['weight'] - $b['weight']; + if ($weight) { + return $weight; + } + } +} \ No newline at end of file diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php b/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php new file mode 100644 index 0000000..181edfc --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/Type/LayoutManager.php @@ -0,0 +1,26 @@ + 'Drupal\layout\Plugin\layout\layout\DefaultLayout' + ); + + public function __construct() { + $this->discovery = new DerivativeDiscoveryDecorator(new AnnotatedClassDiscovery('layout', 'layout')); + $this->factory = new ReflectionFactory($this); + $this->mapper = new LayoutMapper($this); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/LayoutBlock.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/LayoutBlock.php new file mode 100644 index 0000000..542f7e6 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/LayoutBlock.php @@ -0,0 +1,31 @@ +createInstance('default_layout:layout__twocol', $this->configuration['layout']); + return array( + '#children' => $layout->renderLayout() + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageActions.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageActions.php new file mode 100644 index 0000000..e0e6345 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageActions.php @@ -0,0 +1,30 @@ + theme('breadcrumb', array('breadcrumb' => drupal_get_breadcrumb())), + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageMessages.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageMessages.php new file mode 100644 index 0000000..ec73515 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageMessages.php @@ -0,0 +1,30 @@ + theme('status_messages'), + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PagePrimaryLinks.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PagePrimaryLinks.php new file mode 100644 index 0000000..58f352d --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PagePrimaryLinks.php @@ -0,0 +1,30 @@ + theme('links', array('links' => menu_main_menu(), 'attributes' => array('class' => 'links primary-links'))), + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSecondaryLinks.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSecondaryLinks.php new file mode 100644 index 0000000..ab56df7 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSecondaryLinks.php @@ -0,0 +1,30 @@ + theme('links', array('links' => menu_secondary_menu(), 'attributes' => array('class' => 'links secondary-links'))), + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteLogo.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteLogo.php new file mode 100644 index 0000000..13d4925 --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteLogo.php @@ -0,0 +1,34 @@ +'; + return array( + '#children' => l($image, '', array('html' => TRUE, 'attributes' => array('rel' => 'home', 'id' => 'logo', 'title' => t('Home')))), + ); + } + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteName.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteName.php new file mode 100644 index 0000000..3697e4c --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteName.php @@ -0,0 +1,30 @@ + filter_xss_admin(config('system.site')->get('name')), + ); + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteSlogan.php b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteSlogan.php new file mode 100644 index 0000000..890d44a --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/block/block/PageSiteSlogan.php @@ -0,0 +1,35 @@ +get('slogan'); + if (!empty($slogan)) { + return array( + '#children' => filter_xss_admin($slogan), + ); + } + } + } +} diff --git a/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/DefaultLayout.php b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/DefaultLayout.php new file mode 100644 index 0000000..1fce65e --- /dev/null +++ b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/DefaultLayout.php @@ -0,0 +1,115 @@ +getDefinition($plugin_id); + foreach ($definition['regions'] as $region => $title) { + if (!isset($configuration['regions'][$region])) { + $configuration['regions'][$region] = array(); + } + } + parent::__construct($configuration, $plugin_id, $discovery); + } + + /** + * Overrides Drupal\layout\Plugin\LayoutInterface::getRegions(). + */ + public function getRegions() { + $definition = $this->getDefinition(); + return $definition['regions']; + } + + /** + * Add the CSS files associated with this layout to the page. + */ + public function addCss() { + $definition = $this->getDefinition(); + drupal_add_css($definition['path'] . '/' . $definition['css']); + } + + /** + * Add the administrative CSS files associated with this layout to the page. + */ + public function addAdminCss() { + $definition = $this->getDefinition(); + $css = isset($definition['admin css']) ? $definition['admin css'] : $definition['css']; + drupal_add_css($definition['path'] . '/' . $css); + } + + /** + * Add the JS files associated with this layout to the page. + */ + public function addJs() { + $definition = $this->getDefinition(); + if (isset($definition['js'])) { + drupal_add_js($definition['path'] . '/' . $definition['js']); + } + } + + /** + * Overrides Drupal\layout\Plugin\LayoutInterface::renderLayout(). + * + * @todo + * The $regions parameter is here only temporarily. It allows the caller + * to pass already rendered regions, while layout/block configuration code + * is still in progress. + */ + public function renderLayout($admin = FALSE) { + $definition = $this->getDefinition(); + + // Render all regions not already rendered by the caller. + foreach ($this->getRegions() as $region => $title) { + if (!isset($regions[$region]) && isset($this->configuration['regions'][$region])) { + foreach ($this->configuration['regions'][$region] as $block_id => $configuration) { + $block = block_load($block_id, $configuration); + if ($block->access()) { + // Need to check the caching method on the block to determine exactly + // how we're going to get it. Should probably be abstracted out of + // this code so that the renderer worries about it instead. + $block->setConfig('region', $region); + $build = $block->build(); + if ($build) { + $regions[$region][] = array( + '#block' => $block, + '#theme_wrappers' => array('block'), + $build, + ); + } + } + } + $regions[$region] = drupal_render($regions[$region]); + } + } + + if (!$admin) { + $this->addCss(); + $this->addJs(); + } + else { + $this->addAdminCss(); + } + + $template = $definition['path'] . '/' . $definition['template'] . '.tpl.php'; + $output = theme_render_template($template, array('content' => $regions)); + + return $output; + } +} diff --git a/core/themes/bartik/layout/bartik/bartik--bartik.tpl.php b/core/themes/bartik/layout/bartik/bartik--bartik.tpl.php new file mode 100644 index 0000000..87cc199 --- /dev/null +++ b/core/themes/bartik/layout/bartik/bartik--bartik.tpl.php @@ -0,0 +1,69 @@ + +
+ + + + + + + +
+ +
+
+ + +
+ + + + + + + + + +
+ + +
+ + + +
+ + + + +
diff --git a/core/themes/bartik/layout/bartik/bartik.yml b/core/themes/bartik/layout/bartik/bartik.yml new file mode 100644 index 0000000..7ed50bb --- /dev/null +++ b/core/themes/bartik/layout/bartik/bartik.yml @@ -0,0 +1,20 @@ +title: Bartik page +category: Other +icon: page.png +css: page.css +regions: + header: 'Header' + help: 'Help' + highlighted: 'Highlighted' + featured: 'Featured' + content: 'Content' + sidebar_first: 'Sidebar first' + sidebar_second: 'Sidebar second' + triptych_first: 'Triptych first' + triptych_middle: 'Triptych middle' + triptych_last: 'Triptych last' + footer_firstcolumn: 'Footer first column' + footer_secondcolumn: 'Footer second column' + footer_thirdcolumn: 'Footer third column' + footer_fourthcolumn: 'Footer fourth column' + footer: 'Footer' diff --git a/core/themes/bartik/lib/Drupal/bartik/blocks/PrimaryLinks.php b/core/themes/bartik/lib/Drupal/bartik/blocks/PrimaryLinks.php new file mode 100644 index 0000000..05f97a7 --- /dev/null +++ b/core/themes/bartik/lib/Drupal/bartik/blocks/PrimaryLinks.php @@ -0,0 +1,30 @@ + '', + '#children' => theme('links__system_main_menu', array( + 'links' => menu_main_menu(), + 'attributes' => array( + 'id' => 'main-menu-links', + 'class' => array('links', 'clearfix'), + ), + 'heading' => array( + 'text' => t('Main menu'), + 'level' => 'h2', + 'class' => array('element-invisible'), + ), + )), + ); + } +} diff --git a/core/themes/bartik/lib/Drupal/bartik/blocks/SecondaryLinks.php b/core/themes/bartik/lib/Drupal/bartik/blocks/SecondaryLinks.php new file mode 100644 index 0000000..1ada2f1 --- /dev/null +++ b/core/themes/bartik/lib/Drupal/bartik/blocks/SecondaryLinks.php @@ -0,0 +1,30 @@ + '', + '#children' => theme('links__system_secondary_menu', array( + 'links' => menu_secondary_menu(), + 'attributes' => array( + 'id' => 'secondary-menu-links', + 'class' => array('links', 'inline', 'clearfix'), + ), + 'heading' => array( + 'text' => t('Secondary menu'), + 'level' => 'h2', + 'class' => array('element-invisible'), + ), + )), + ); + } +} diff --git a/core/themes/bartik/template.php b/core/themes/bartik/template.php index 5373c92..d4facdc 100644 --- a/core/themes/bartik/template.php +++ b/core/themes/bartik/template.php @@ -151,3 +151,12 @@ function bartik_field__taxonomy_term_reference($variables) { return $output; } + +/** + * Implements hook_block_alter(). + */ +function bartik_block_alter(&$definitions) { + $definitions['page_primary_links']['class'] = 'Drupal\\bartik\\blocks\\PrimaryLinks'; + $definitions['page_secondary_links']['class'] = 'Drupal\\bartik\\blocks\\SecondaryLinks'; +} +