This is a sub-issue of #1787634: [META] Decouple layouts from themes.

Problem/Motivation

Layouts are only defined in code so far and there are no user interface elements to expose them yet. For blocks to be placed in layouts first we need a layout browser that shows what kind of layouts are available. The code built for this layout overview can be later reused to do block placement administration as well.

Proposed solution

Proposed (still in the works) designs for this page looks like the following:

List of layout templates (note template terminology used for this on the user interface):
Templates.jpg

One specific layout template demonstrated:
OneTemplate.jpg

The proposal is to add this new page in the layout module itself because this merely needs the rendered layouts to demonstrate their setup.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Gábor Hojtsy’s picture

Status: Active » Needs review
FileSize
8.95 KB
22.72 KB
33.12 KB

Attached patch implements an initial version of this. Screenshots:

Listing:
Templates01.jpg

Individual demo (note that this is the most complex layout in core):
Templates02.jpg

Notes:

1. The design renames layouts to *templates* and uses layouts for populated templates, where block placement is already present. This is pretty misleading in the permissions code for example where the internal name says 'administer layouts' but the external facing label is 'Administer templates'. Don't really know how to overcome this without renaming the module / concept or stepping back on terminology.

2. The design puts the template listing to the Appearance area. This is not really ready ATM to house sub-items in Drupal 8 (it is a top level admin page), so I just put this under structure for now. We can debate how Appearance should look like somewhere else, enough ontopic debatables here :)

3. The listing page does not have any of the fancy checkboxes since there are no operations to do. It does not have "usage" information given that we don't use layouts for anything yet, so no way to get where it is used. Also View is the only operation, which I think as per Drupal standards should be implemented as a link on the name of the template itself. I did it in a dropbutton for now.

4. Layout plugin definitions did not know who their provider was, I added this in the definition accessible under $layout['provider'] so we can tell people where a layout template came from.

5. Needed to use some funky t() patterns since I'm t()-ing a dynamic value which has a finite set of possible values. Using switch or ?: is also a possibility if we want to make this differently puzzling. Speaking of which looks like install profiles cannot provide layouts: #1839288: Install profiles cannot provide layouts

6. The internal names for layout plugins is not very nice, but that is their machine name, so needed to expose that in the URL (admin/structure/templates/manage/static_layout%3Alayout__two-col). Also, plugins don't know how they are referred to (or I could not find this starting from a plugin instance), so I needed to forego using a menu item loader to load the layout instance and instead passed on the layout plugin key directly. This necessitated a custom access callback.

7. The actual demonstration needs to load the definition, so it can include the name of the layout in the page, but creating an instance only requires a key. Then although when creating the instance we could populate the region configuration, we cannot yet invoke the getRegions() method to get the list of regions to populate for demonstration, so I needed to add back the renderLayout() $regions argument that was in an earlier version of the layout patch, so we can inject from the outside. Unless there is a way to overwrite plugin config later after instantiation.

8. Speaking of which, I removed the header3 demo text from layout rendering and now do it specifically in the layout_test module where it is being tested for. Not in this actual demonstration where additional markup is injected to avoid messing with the layout for the demo.

9. I added some v0.1 CSS to demonstrate the layout. I'm sure actual frontend developers can do much better. I just used a web gradient generator to try to replicate the design. :D

10. Finally, also fixed some LayoutInterface docs so it reflects what is going on better.

Status: Needs review » Needs work

The last submitted patch, layout-template-demonstration-1.patch, failed testing.

tkoleary’s picture

1. The design renames layouts to *templates* and uses layouts for populated templates...

Yes. My strong feeling here is that we need to step back on teminology. I think this nomenclature discussion that has gone around in circles is neatly solved for both the themer and the site builder by this change. Themers will expect a template to map to a twig template, which will be the case; site builders will expect a layout to be the place where they "lay out" the blocks on their pages.

2. The design puts the template listing to the Appearance area...

Changed in IA based on Lisa's study.

3. The listing page does not have any of the fancy checkboxes since there are no operations to do...

Agreed. Updating the design.

4-8 I can't answer

9. I added some v0.1 CSS...

I will send you over all the attributes from the design.

Gábor Hojtsy’s picture

Status: Needs work » Needs review
FileSize
1.27 KB
8.66 KB

Updated to include view link right in the table instead of operations. Since no other operation was left, removed the operations column. More feedback welcome!

Gábor Hojtsy’s picture

Also fix existing layout demonstration tests so that they get the sample content they were looking for.

Gábor Hojtsy’s picture

Issue tags: +Spark

Tagging for spark.

Gábor Hojtsy’s picture

Any feedback? Anybody want to see this happen in Drupal 8?

yoroy’s picture

Overall: yes, I'd want to see this happen in D8.

I'm unsure about which level of feedback is most constructive at the moment but here goes:

1. I'm not clear yet on the distinction between templates and layouts. Are templates the 'object' and layouts 'instances' of an object? Why are these seperate things? Do they need equal emphasis in how discoverable they are in the admin IA?

The listing

2. Gabor's number 4: 'Source' column, necessary to know this for whom? I would think it's not so important to have it shown on the overview page.
3. I would prefer to see thumnails of the templates' structure instead (similar to the ones you see in panels when choosing a layout)

The detail page

4. I'm assuming this is purely scaffolding right now, since it doesn't look I can do anything here at this stage :)

---

Gabor: Which of your questions need feedback/answers most in order to proceed constructively?

Gábor Hojtsy’s picture

@yoroy: I just created this fascinating little figure about our terminology mash-up, because I got continually confused. Now I have a place to refer and maybe a hope we will fix this all up when the time comes. :D

On point 2 , I agree the source might be too much information, it might be relevant if you want to figure out if you can disable a module or not, so you know if your layouts will go fubar or not.

3: Well, core does not (yet?) have such images for layouts, but I agree that would be useful.

4. No, this feature is purely presentational, there is nothing to act on there. Templates are wireframes, this just demonstrates the wireframe. You have no other way to look at them, because #1841584: Add and configure master displays would only let you do it in a very backwards way (you'd need to switch your master layouts and not save them to preview) and #1840500: Add simple blank page creation capability does not have the capability either to use alternate templates. So this is THE place to review how alternate templates look and then maybe go and configure your master layouts with them.

Gábor Hojtsy’s picture

Title: Add listing of layout templates » Add listing and demonstration of layout templates
yoroy’s picture

Title: Add listing and demonstration of layout templates » Add listing of layout templates

1. Glad to hear I'm not alone in this. Sad to hear I'm not alone in this :-). My naming scheme based on your graphic would now be:

Layout (amount and stacking of regions) -> Master page (or Template) -> Page
So, Layout > Master page > Page, or even
Template > Master page > Page

I imagine that permissions would let you protect editors from having to mess with the first 'layout' layer, leaving them with a Master page from which to create individual pages. Look at powerpoint and indesign for example, they both have this concept of Master pages.

Hmmm.

Of all the possible words to use in this context, I feel 'Layout' is the weakest when used as a noun. A certain layout is more the result from all the work you put into a creating a page then one of the ingredients you added in doing so.

Template > Master page > Page

I'm not fond of the 'landing page' either, it has quite different meanings depending who's talking about them. I understand this comes from the choice to rebrand 'creating content' as 'creating pages', which I'm also very sceptical about.

So… my main points would be:

- Try to avoid having to use 'Layout' as a noun in this triad
- Consider introducing 'Master pages'
- 'Landing pages' is iffy and seems a work-around label because 'page' is given away too early in the creatin stack (replacing 'content')

You create content, it lives on a page, which is based on a master page which is derived from a template.

tkoleary’s picture

FileSize
287.35 KB

Hi Roy,

Thanks for the feedback. Adding the master page is exactly what we are planning for phase 2 of this once we have built out the ability to create one off landing pages. I think there is still some misunderstanding about how this all works though so I have attached a diagram to illustrate how I understand it.

All the nomenclature is user facing and reflects what is in the design right now.

tkoleary’s picture

FileSize
287.47 KB

Diagram

diagram

Gábor Hojtsy’s picture

Title: Add listing of layout templates » Add layout template demonstration
FileSize
10.5 KB

#1817044: Implement Display, a type of config for use by layouts, et. all was committed since I rolled #5 so that did not apply anymore. Rerolled.

Gábor Hojtsy’s picture

Further fixes since the display patch introduced region types, which this patch was not ready for yet.

Gábor Hojtsy’s picture

Anybody sees holes in this implementation? I hoped to get this in fast, but without much interest, it is pretty hard... I'd hoped to build other key pieces in #1787634: [META] Decouple layouts from themes on top of this one. What about all the unanswered questions in #1?

andypost’s picture

Implementation is clear, except access. Also it's good to have 'configure' link in module's info file.
Help text could be adjusted latter

+++ b/core/modules/layout/layout.module
@@ -6,6 +6,48 @@
+    'page callback' => 'layout_page_view',
+    'page arguments' => array(4),
+    'access callback' => 'layout_user_access',
...
+  return (user_access('administer layouts') && layout_manager()->getDefinition($key));
...
+    'administer layouts' => array(
+      'title' => t('Administer templates'),

Suppose this permission should be "view layout" or "layout overview". This screen is a view only

Gábor Hojtsy’s picture

@andypost: although it is view only, it is presented in an admin-only context, so I think "administer" makes sense. It is part of the admin user experience. Also, because its a view only, it does not make sense to have a configure link pointing to here, you are not configuring anything here.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

So it looks ready. Further clean-ups and re-factoring could be done in follow-ups.
There's no data changes introduced so not sure we need tests for this

+++ b/core/modules/layout/layout.admin.cssundefined
@@ -0,0 +1,26 @@
+  background: rgb(224, 224, 224);

maybe background-color?

+++ b/core/modules/layout/layout.admin.cssundefined
@@ -0,0 +1,26 @@
+  background-image: 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: -moz-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: -ms-linear-gradient(bottom, rgb(70,70,71) 40%, rgb(91,91,94) 70%, rgb(125,124,125) 88%);
...
+  background-image: -webkit-gradient(

needs follow-up to discuss styling

+++ b/core/modules/layout/layout.admin.incundefined
@@ -0,0 +1,66 @@
+  $build = array();
+  $build['table'] = array(
+    '#theme' => 'table',
+    '#header' => $header,
+    '#rows' => $rows,
+  );
+  return $build;

useless variable init, no #empty key

+++ b/core/modules/layout/layout.admin.incundefined
@@ -0,0 +1,66 @@
+  t('module');
+  t('theme');

this could be used as array to skip wrong providers in loop above

Gábor Hojtsy’s picture

@andypost: I think the CSS can/should be refactored and corrected sometime, but I agree if there is nobody interested at this point to work on this, it can be done later just as well. As for missing #empty, I sincerely hope there are no sites without layout templates, every theme in Drupal 8 should have at least one layout template defined while core will have several more defined. If there are no layout templates defined, then you cannot even place any content on any page. As for "wrong" providers, we do now there can only be themes and modules as per the plugin implementation.

Gábor Hojtsy’s picture

Let's not introduce XSS via the name of the template, although those who can provide these templates are themers or module developers now who would do more damage with PHP code.

kbell’s picture

Just some general feedback:

1. I like Gabor's #5 demo patch.

2. I too dislike use of label Landing Pages in *any* usage here for reasons cited plus I've always just found the term leads to more confusion than clarity.

3. I support Roy's point about matching current usage/terminology in page composition programs like InDesign for consistency but am still thinking there are too many (redundant) levels here, ie we're overcomplicating matters (here I'm referring to tkoleary's 4-stage diagram in #13 above). If dismissing term "Layouts" here is an option, my strongest preference is for Roy's "Template > Master page > Page" setup in #11.

4. Permission should read "View Layouts" (or even better if possible, "View Master Pages" - re #17).

5. I do, very much, wish to see this included in Drupal 8.

6. About the layout/arrangement "icons", Panopoly (http://drupal.org/project/panopoly) has a nice implementation of this idea, I support using these (http://drupal.org/files/images/panoply-icon-smaller-still.png).

7. In general, I support Panopoly's UI setup and the advances in UI that have been made there for inclusion in Drupal 8. I left Denver with rather the impression that we were planning to use it as the base for UI in Drupal 8. Has that plan been scrapped? Please pardon if I've misunderstood the directive.

Gábor Hojtsy’s picture

@kbell: we need to get stuff in step by step. Ideally this would have happened earlier as part of the blocks and layouts initiative not this late in the cycle, but that is how it is. A big drop of code mass is not reviewable is not easy to apply to Drupal 8. Views took months to port to Drupal 8 proper (using the new entity/config/plugin/etc. techniques). Porting the whole of panopoly could very well be a similar effort. We chose not to port the whole system in contrib but to get our foot in core first and then iterate with experience and include other improvements as needed/useful/possible.

kbell’s picture

Thanks for the update, Gábor - much appreciated!
Cheers,
Kelly

xjm’s picture

Docs cleanups that can also be done in a followup (or a reroll; I added this to the office hours task list).

  1. +++ b/core/modules/layout/layout.admin.cssundefined
    @@ -0,0 +1,26 @@
    +.layout-region-demonstration {
    +  color: white;
    +  margin: 3px;
    +  padding: 10px;
    +  text-transform: uppercase;
    +  font-size: 0.8em;
    +
    +  background-image: 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: -moz-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: -ms-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))
    +  );
    

    I think these properties are in the wrong order. Reference: http://drupal.org/node/302199.

  2. +++ b/core/modules/layout/layout.admin.incundefined
    @@ -0,0 +1,66 @@
    + * Page callback: Presents list of layouts.
    

    Should have an article ("Presents a list of layouts").

  3. +++ b/core/modules/layout/layout.admin.incundefined
    @@ -0,0 +1,66 @@
    + * Page callback: Demonstrate a layout template.
    
    +++ b/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.phpundefined
    @@ -76,6 +76,19 @@ function testDerivatives() {
    +   * Render the layout with sample region content.
    

    Demonstrates, Renders. :) Reference: http://drupal.org/node/1354#functions

  4. +++ b/core/modules/layout/layout.moduleundefined
    @@ -6,6 +6,48 @@
    + * Menu access callback. Check for layout existance.
    + */
    +function layout_user_access($key) {
    

    "Existence" is misspelled and the summary format is nonstandard. Should be:
    Access callback: Checks the existence of a layout.
    Also, the $key parameter needs to be documented. Reference: http://drupal.org/node/1354#menu-callback

  5. +++ b/core/modules/layout/lib/Drupal/layout/Plugin/LayoutInterface.phpundefined
    @@ -18,15 +18,24 @@
    +   * @param boolean $admin
    +   *   TRUE if the rendered layout is displayed in an administrative context,
    +   *   FALSE otherwise.
    +   * @param array $regions
    +   *   An array of region render arrays keyed by region machine names.
    ...
    +  public function renderLayout($admin = FALSE, $regions = array());
    

    It looks like these parameters are optional, so they should have (optional) at the beginning of the description. Also, it should be bool (not boolean). Reference: http://drupal.org/node/1354#param-return-data-type

bdone’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
11.02 KB

docs clean up from #25, rerolled against #21.

bdone’s picture

FileSize
4.77 KB

adding an interdiff.txt for #26

xjm’s picture

Excellent, thanks @bdone! This looks great. I gave it another read and caught some undocumented parameters, plus a couple of minor corrections:

  1. +++ b/core/modules/layout/layout.admin.incundefined
    @@ -0,0 +1,66 @@
    +/**
    + * Page callback: Demonstrates a layout template.
    + *
    + * @see layout_menu()
    + */
    +function layout_page_view($key) {
    

    It looks like $key and the return value are also undocumented here, so can we add documentation for it too?

  2. +++ b/core/modules/layout/layout.moduleundefined
    @@ -6,6 +6,55 @@
    + * @return
    + *   TRUE if the current user can access page layout menu items; FALSE
    + *   otherwise.
    

    This should be @return bool to document the data type.

  3. +++ b/core/modules/layout/lib/Drupal/layout/Plugin/layout/layout/StaticLayout.phpundefined
    @@ -87,12 +87,10 @@ public function renderLayout($admin = FALSE) {
    -    // Render all regions needed for this layout.
    +    // Renders all regions needed for this layout.
    
    +++ b/core/modules/layout/lib/Drupal/layout/Tests/LayoutDerivativesTest.phpundefined
    @@ -76,6 +76,19 @@ function testDerivatives() {
       /**
    +   * Render the layout with sample region content.
    +   */
    +  function renderLayoutDemonstration($layout) {
    

    Oops, I should have included more context here. It's the docblock that needs to be "Renders" (as in "This function renders"). For inline comments, it's still "render" as in "do this now".

    I also notice now that the method is missing its @param and @return documentation.

bdone’s picture

parameter documentation and minor fixes, per @xjm's comments in #28.

xjm’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @bdone! RTBC again.

webchick’s picture

Awesome, thanks!

We're up over thresholds, but I plan to commit this the second we're under again, since it's been hanging around for quite some time. :)

Bojhan’s picture

We are kinda under, the are like 5 tasks which are changelog :D

webchick’s picture

Status: Reviewed & tested by the community » Fixed

We're still over, but it's close enough for government work atm.

Committed and pushed to 8.x. Thanks! And thanks to bdone for the docs improvements, too! :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

webchick’s picture

Issue tags: +revisit before beta

Tagging with "revisit before release"... if it turns out the other blocks and layouts work doesn't land (it's been stalled for quite awhile, which makes this unfortunately likely... :\) we'll need to rip this out.

webchick’s picture

Issue summary: View changes

Add meta issue link.

catch’s picture