diff --git a/panels.info.yml b/panels.info.yml index 0778575..741db19 100644 --- a/panels.info.yml +++ b/panels.info.yml @@ -7,3 +7,4 @@ core: 8.x configure: panels.admin dependencies: - page_manager + - layout_plugin diff --git a/panels.layouts.yml b/panels.layouts.yml new file mode 100644 index 0000000..c2fa131 --- /dev/null +++ b/panels.layouts.yml @@ -0,0 +1,27 @@ +onecol: + label: Single column + category: Columns: 1 + type: page + path: plugins/layouts/onecol + # @todo Add support for icon: https://www.drupal.org/node/2326595 + icon: onecol.png + css: onecol.css + theme: panels_onecol + regions: + middle: + label: Middle column + +twocol: + label: Two column + category: Columns: 2 + type: page + path: plugins/layouts/twocol + # @todo Add support for icon: https://www.drupal.org/node/2326595 + icon: twocol.png + css: twocol.css + theme: panels_twocol + regions: + left: + label: Left side + right: + label: Right side diff --git a/panels.module b/panels.module index 4bb3bad..ce48f80 100644 --- a/panels.module +++ b/panels.module @@ -30,12 +30,45 @@ function panels_api_version() { * Implementation of hook_theme() */ function panels_theme() { - // Safety: go away if CTools is not at an appropriate version. - if (!module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { - return array(); + $theme = array(); + + // For now, we register these theme functions manually. + // @todo: Reimplement the code below to auto register the theme functions + // with current layout plugins. + $theme['panels_onecol'] = array( + 'render element' => 'content', + 'path' => drupal_get_path('module', 'panels') . '/plugins/layouts/onecol', + 'template' => 'panels-onecol', + ); + $theme['panels_twocol'] = array( + 'render element' => 'content', + 'path' => drupal_get_path('module', 'panels') . '/plugins/layouts/twocol', + 'template' => 'panels-twocol', + ); + + /* + $layouts = panels_get_layouts(); + foreach ($layouts as $name => $data) { + foreach (array('theme', 'admin theme') as $callback) { + if (!empty($data[$callback])) { + $theme[$data[$callback]] = array( + 'variables' => array('css_id' => NULL, 'content' => NULL, 'settings' => NULL, 'display' => NULL, 'layout' => NULL, 'renderer' => NULL), + 'path' => $data['path'], + 'file' => $data['file'], + ); + + // if no theme function exists, assume template. + if (!function_exists("theme_$data[theme]")) { + $theme[$data[$callback]]['template'] = str_replace('_', '-', $data[$callback]); + $theme[$data[$callback]]['file'] = $data['file']; // for preprocess. + } + } + } } + */ - $theme = array(); + // @todo: Port the follow to Drupal 8! + /* $theme['panels_layout_link'] = array( 'variables' => array('title' => NULL, 'id' => NULL, 'image' => NULL, 'link' => NULL, 'class' => NULL), ); @@ -99,27 +132,6 @@ function panels_theme() { // Register layout and style themes on behalf of all of these items. ctools_include('plugins', 'panels'); - // No need to worry about files; the plugin has to already be loaded for us - // to even know what the theme function is, so files will be auto included. - $layouts = panels_get_layouts(); - foreach ($layouts as $name => $data) { - foreach (array('theme', 'admin theme') as $callback) { - if (!empty($data[$callback])) { - $theme[$data[$callback]] = array( - 'variables' => array('css_id' => NULL, 'content' => NULL, 'settings' => NULL, 'display' => NULL, 'layout' => NULL, 'renderer' => NULL), - 'path' => $data['path'], - 'file' => $data['file'], - ); - - // if no theme function exists, assume template. - if (!function_exists("theme_$data[theme]")) { - $theme[$data[$callback]]['template'] = str_replace('_', '-', $data[$callback]); - $theme[$data[$callback]]['file'] = $data['file']; // for preprocess. - } - } - } - } - $styles = panels_get_styles(); foreach ($styles as $name => $data) { if (!empty($data['render pane'])) { @@ -146,6 +158,7 @@ function panels_theme() { } } } + */ return $theme; } diff --git a/plugins/layouts/onecol/panels-onecol.html.twig b/plugins/layouts/onecol/panels-onecol.html.twig new file mode 100644 index 0000000..0906cd7 --- /dev/null +++ b/plugins/layouts/onecol/panels-onecol.html.twig @@ -0,0 +1,19 @@ +{# +/** + * @file + * Template for a 3 column panel layout. + * + * This template provides a very simple "one column" panel display layout. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * $content['middle']: The only panel in the layout. + */ +#} +
+
+
{{ content.middle }}
+
+
diff --git a/plugins/layouts/onecol/panels-onecol.tpl.php b/plugins/layouts/onecol/panels-onecol.tpl.php deleted file mode 100644 index 73ad5b8..0000000 --- a/plugins/layouts/onecol/panels-onecol.tpl.php +++ /dev/null @@ -1,19 +0,0 @@ - -
> -
-
-
-
diff --git a/plugins/layouts/twocol/panels-twocol.html.twig b/plugins/layouts/twocol/panels-twocol.html.twig new file mode 100644 index 0000000..d1796ef --- /dev/null +++ b/plugins/layouts/twocol/panels-twocol.html.twig @@ -0,0 +1,25 @@ +{# +/** + * @file + * Template for a 2 column panel layout. + * + * This template provides a two column panel display layout, with + * each column roughly equal in width. + * + * Variables: + * - $id: An optional CSS id to use for the layout. + * - $content: An array of content, each item in the array is keyed to one + * panel of the layout. This layout supports the following sections: + * - $content['left']: Content in the left column. + * - $content['right']: Content in the right column. + */ +#} +
+
+
{{ content.left }}
+
+ +
+
{{ content.right }}
+
+
diff --git a/plugins/layouts/twocol/panels-twocol.tpl.php b/plugins/layouts/twocol/panels-twocol.tpl.php deleted file mode 100644 index 2cda08e..0000000 --- a/plugins/layouts/twocol/panels-twocol.tpl.php +++ /dev/null @@ -1,25 +0,0 @@ - -
> -
-
-
- -
-
-
-
diff --git a/src/Plugin/DisplayVariant/PanelsDisplayVariant.php b/src/Plugin/DisplayVariant/PanelsDisplayVariant.php index f877c90..54b4271 100644 --- a/src/Plugin/DisplayVariant/PanelsDisplayVariant.php +++ b/src/Plugin/DisplayVariant/PanelsDisplayVariant.php @@ -25,6 +25,8 @@ use Drupal\page_manager\Plugin\ConditionVariantTrait; use Drupal\page_manager\Plugin\ContextAwareVariantInterface; use Drupal\page_manager\Plugin\ContextAwareVariantTrait; use Drupal\page_manager\Plugin\PageAwareVariantInterface; +use Drupal\layout_plugin\Layout; +use Drupal\layout_plugin\Plugin\Layout\LayoutInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -42,6 +44,13 @@ class PanelsDisplayVariant extends VariantBase implements ContextAwareVariantInt use ConditionVariantTrait; /** + * The layout handler. + * + * @var \Drupal\layout_plugin\Plugin\Layout\LayoutInterface + */ + protected $layout; + + /** * The context handler. * * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface @@ -108,9 +117,33 @@ class PanelsDisplayVariant extends VariantBase implements ContextAwareVariantInt } /** + * Returns instance of the layout plugin used by this page variant. + * + * @return \Drupal\layout_plugin\Plugin\Layout\LayoutInterface + * Layout plugin instance. + */ + public function getLayout() { + if (!isset($this->layout)) { + $this->layout = Layout::layoutPluginManager()->createInstance($this->configuration['layout'], array()); + } + return $this->layout; + } + + /** * {@inheritdoc} */ - public function build() { + public function getRegionNames() { + return $this->getLayout()->getRegionNames(); + } + + /** + * Build render arrays for each of the regions. + * + * @return + * An associative array keyed by region id, containing the render array + * representing the content of each region. + */ + protected function buildRegions() { $build = array(); $contexts = $this->getContexts(); foreach ($this->getRegionAssignments() as $region => $blocks) { @@ -151,11 +184,29 @@ class PanelsDisplayVariant extends VariantBase implements ContextAwareVariantInt /** * {@inheritdoc} */ + public function build() { + $regions = $this->buildRegions(); + if ($layout = $this->getLayout()) { + return $layout->build($regions); + } + return $regions; + } + + /** + * {@inheritdoc} + */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); // Do not allow blocks to be added until the display variant has been saved. if (!$this->id()) { + $form['layout'] = array( + '#title' => $this->t('Layout'), + '#type' => 'select', + '#options' => Layout::getLayoutOptions(array('group_by_category' => TRUE)), + '#default_value' => NULL + ); + return $form; } @@ -329,9 +380,13 @@ class PanelsDisplayVariant extends VariantBase implements ContextAwareVariantInt public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); + if ($form_state->hasValue('layout')) { + $this->configuration['layout'] = $form_state->getValue('layout'); + } + // If the blocks were rearranged, update their values. - if (!empty($form_state['values']['blocks'])) { - foreach ($form_state['values']['blocks'] as $block_id => $block_values) { + if ($form_state->hasValue('blocks')) { + foreach ($form_state->getValue('blocks') as $block_id => $block_values) { $this->updateBlock($block_id, $block_values); } }