diff --git a/core/modules/layout/layout.info b/core/modules/layout/layout.info
new file mode 100644
index 0000000..e6e4a66
--- /dev/null
+++ b/core/modules/layout/layout.info
@@ -0,0 +1,5 @@
+name = Layout
+description = Provide abstract layout handling for html delivering routes.
+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..a8b5ef9
--- /dev/null
+++ b/core/modules/layout/layout.module
@@ -0,0 +1,27 @@
+get('plugin.manager.layout');
+}
+
+function layout_init() {
+ drupal_set_message('
' . var_export(layout_manager()->getDefinition('default_layout:layout__onecol'), TRUE) . '
');
+}
+
+/**
+ * Implements hook_theme().
+ */
+function layout_theme($existing, $type, $theme, $path) {
+ foreach (layout_manager()->getDefinitions() as $name => $layout) {
+ $variables = array('css_id' => NULL, 'renderer' => NULL);
+ foreach (array_keys($layout['regions']) as $key) {
+ $variables[$key] = NULL;
+ }
+ $theme[$layout['theme']] = array(
+ 'variables' => $variables,
+ 'path' => $layout['path'],
+ 'template' => str_replace('_', '-', $layout['theme']),
+ );
+ }
+ return $theme;
+}
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..73ad5b8
--- /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..83f284a
--- /dev/null
+++ b/core/modules/layout/layout/onecol/onecol.css
@@ -0,0 +1,22 @@
+
+.panel-1col {
+/* overflow: hidden; */
+}
+
+.panel-2col .panel-col-first .inside {
+ margin: 0;
+}
+
+
+.panel-1col .panel-col {
+ width: 100%;
+}
+
+#panels-edit-display .panel-pane,
+#panels-edit-display .helperclass {
+ margin: .5em;
+}
+
+.panel-2col .panel-separator {
+ margin: 0 0 1em 0;
+}
diff --git a/core/modules/layout/layout/onecol/onecol.png b/core/modules/layout/layout/onecol/onecol.png
new file mode 100644
index 0000000..176ed69
Binary files /dev/null and b/core/modules/layout/layout/onecol/onecol.png differ
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..2cda08e
--- /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..6e53eca
--- /dev/null
+++ b/core/modules/layout/layout/twocol/twocol.css
@@ -0,0 +1,37 @@
+
+.panel-2col {
+/* overflow: hidden; */
+}
+
+.panel-2col .panel-col-first {
+ float: left;
+ width: 50%;
+}
+* html .panel-2col .panel-col-first {
+ width: 49.9%;
+}
+
+.panel-2col .panel-col-first .inside {
+ margin: 0 .5em 1em 0;
+}
+
+.panel-2col .panel-col-last {
+ float: left;
+ width: 50%;
+}
+* html .panel-2col .panel-col-last {
+ width: 49.9%;
+}
+
+.panel-2col .panel-col-last .inside {
+ margin: 0 0 1em .5em;
+}
+
+#panels-edit-display .panel-pane,
+#panels-edit-display .helperclass {
+ margin: .5em;
+}
+
+.panel-2col .panel-separator {
+ margin: 0 0 1em 0;
+}
diff --git a/core/modules/layout/layout/twocol/twocol.png b/core/modules/layout/layout/twocol/twocol.png
new file mode 100644
index 0000000..9d2965e
Binary files /dev/null and b/core/modules/layout/layout/twocol/twocol.png differ
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..1591b6e
--- /dev/null
+++ b/core/modules/layout/lib/Drupal/layout/LayoutBundle.php
@@ -0,0 +1,24 @@
+register('plugin.manager.layout', 'Drupal\layout\Plugin\Type\LayoutManager');
+ }
+}
\ No newline at end of file
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..a39ef95
--- /dev/null
+++ b/core/modules/layout/lib/Drupal/layout/Plugin/Derivative/Layout.php
@@ -0,0 +1,66 @@
+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;
+ }
+
+ 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')]['theme'] = $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..7bbfaad
--- /dev/null
+++ b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.php
@@ -0,0 +1,11 @@
+ 'Drupal\layout\Plugin\layout\layout\DefaultLayout'
+ );
+
+ public function __construct() {
+ $this->discovery = new DerivativeDiscoveryDecorator(new AnnotatedClassDiscovery('layout', 'layout'));
+ $this->factory = new ReflectionFactory($this);
+ }
+}
\ No newline at end of file
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..8e66105
--- /dev/null
+++ b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/DefaultLayout.php
@@ -0,0 +1,62 @@
+getDefinition();
+ return $definition['regions'];
+ }
+
+ public function getCss() {
+ $definition = $this->getDefinition();
+ drupal_add_css($definition['path'] . '/' . $definition['css']);
+ }
+
+ public function getAdminCss() {
+ $definition = $this->getDefinition();
+ $css = isset($definition['admin css']) ? $definition['admin css'] : $definition['css'];
+ drupal_add_css($definition['path'] . '/' . $css);
+ }
+
+ public function getJs() {
+ $definition = $this->getDefinition();
+ if (isset($definition['js'])) {
+ drupal_add_js($definition['path'] . '/' . $definition['js']);
+ }
+ }
+
+ public function renderLayout(RendererInterface $renderer, $admin = FALSE) {
+ $definition = $this->getDefinition();
+ $regions = array();
+ foreach ($this->getRegions() as $region => $title) {
+ 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.
+ $regions[$region][] = $block->build();
+ }
+ }
+ }
+ if (!$admin) {
+ $this->getCss();
+ $this->getJs();
+ }
+ else {
+ $this->getAdminCss();
+ }
+ return theme($definition['layout'], $regions);
+ }
+}
\ No newline at end of file