Save 37% off PRO during our Black Friday Sale! »

Partials - A DRY template pattern. Now a part of EE core.

Partials - A DRY template pattern. Now a part of EE core.

Slides for my presentation about the "partials" template development pattern, presented at the 2014 GeeUp conference in Leiden, Netherlands: http://geeuphq.com

July 1 2014 Update: Amended slide 38 to indicate EE 2.9 changes, no longer are you able to explicitly set layout:contents in your parent template.

384bbbb8c8ca442ed3752767095f690b?s=128

John D Wells

June 20, 2014
Tweet

Transcript

  1. @johndwells – GeeUp 2014 PARTIALS A DRY template pattern. Now

    a part of EE core. Partials
  2. @johndwells – GeeUp 2014 PARTIALS Goals • What are “partials”

    • In action with EE 2.8’s {layout=} tag • Common use cases & tricks
  3. @johndwells – GeeUp 2014 PARTIALS Stash

  4. @johndwells – GeeUp 2014 PARTIALS Stash Sorry, Mark!

  5. @johndwells – GeeUp 2014 PARTIALS Patterns …a general reusable solution

    to a commonly occurring problem within a given context… http://en.wikipedia.org/wiki/Software_design_pattern
  6. @johndwells – GeeUp 2014 PARTIALS Content Sandwich http://xkcd.com/149

  7. @johndwells – GeeUp 2014 PARTIALS

  8. @johndwells – GeeUp 2014 PARTIALS

  9. @johndwells – GeeUp 2014 PARTIALS

  10. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  11. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  12. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  13. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  14. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  15. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  16. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  17. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  18. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {embed=“embeds/_html_head” title=“Blog”}!

    3. <body class=“blog”>! 4. {embed=“embeds/_nav” active=“blog”}! 5. <main> … </main>! 6. {snippet_sidebar}! 7. {snippet_footer}! 8. </body>! 9. {snippet_html_foot}
  19. @johndwells – GeeUp 2014 PARTIALS Downsides • Code repetition -

    every calling template must “know” overall structure of final output • Risk of single DOM elements spanning multiple embeds • Difficult to pass content through to embeds (e.g. <title>) • Performance hits through multiple embeds & snippets
  20. @johndwells – GeeUp 2014 PARTIALS Partials Solve Problems

  21. @johndwells – GeeUp 2014 PARTIALS

  22. @johndwells – GeeUp 2014 PARTIALS Content Goes Here

  23. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <head>! 3.

    <title> … </title>! 4. </head>! 5. <body>! 6. <header> … </header>! 7. <main>CONTENT GOES HERE</main>! 8. <footer> … </footer>! 9. </body>! 10. </html>
  24. @johndwells – GeeUp 2014 PARTIALS

  25. @johndwells – GeeUp 2014 PARTIALS

  26. @johndwells – GeeUp 2014 PARTIALS <CONTENT GOES HERE>

  27. @johndwells – GeeUp 2014 PARTIALS ! {layout=“_layouts/index”}! ! ! !

    ! !
  28. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. <div class=“blog-listings”>! 5. {exp:channel:entries}! 6. …! 7. {/exp:channel:entries}! 8. </div>
  29. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <head>! 3.

    <title> … </title>! 4. </head>! 5. <body>! 6. <header> … </header>! 7. <main>{layout:contents}</main>! 8. <footer> … </footer>! 9. </body>! 10. </html>
  30. @johndwells – GeeUp 2014 PARTIALS Level Up

  31. @johndwells – GeeUp 2014 PARTIALS Terms • “Layout” is the

    EE template which contains your wrapping/container markup. • “Parent” is the calling EE template that uses the {layout=} tag • “Layout Variables” are the partials that we pass from our Parent template to our Layout template.
  32. @johndwells – GeeUp 2014 PARTIALS Rules • {layout=} must be

    the first tag in your parent template, before any other tags • There may be only one {layout=} tag present in any one parent template. • {layout:contents} is reserved as the default variable containing the default output of your parent template.
  33. @johndwells – GeeUp 2014 PARTIALS Setters & Getters

  34. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index” title=“Blog”}!

    3. ! 4. ! 5. ! 6. ! 7. ! 8.
  35. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index” title=“Blog”}!

    3. ! 4. {layout:set name=“title” value=“Blog”}! 5. ! 6. ! 7. ! 8.
  36. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index” title=“Blog”}!

    3. ! 4. {layout:set name=“title” value=“Blog”}! 5. ! 6. {layout:set name=“title”}! 7. Blog! 8. {/layout:set}
  37. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. Automatically set to {layout:contents}
  38. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. {layout:set name=“contents”}! 5. Not possible as of EE 2.9 :(! 6. {/layout:set}
  39. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index” title=“Foo”}!

    3. ! 4. {layout:set name=“title” value=“Bar”}
  40. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. {layout:set name=“title” value=“Bar”}! 5. ! 6. {layout:set name=“title”}! 7. Baz! 8. {/layout:set}
  41. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. {layout:set name=“contents”}! 5. FTW!! 6. {/layout:set}! 7. ! 8. I lose :(
  42. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. ! 3.

    {layout:contents}
  43. @johndwells – GeeUp 2014 PARTIALS Low’s Order? Parse Order

  44. @johndwells – GeeUp 2014 PARTIALS 1. Determine template to process

    based on request URI 2. Get template from database, check template access permissions, and increment the hit counter 3. If it exists, get template from file 4. If template type is static, return template and end parsing 5. Parse (as a group, so order is irrelevant): {freelancer_version}, Snippets, MSM variables, and {last_segment} 6. Parse segment variables 7. Parse embed variables 8. Parse layout variables 9. Parse date formatting string constants 10.Parse {template_edit_date} 11.Parse {current_time} 12.If present, get cached template, then skip to the advanced conditionals parsing stage 13.Parse PHP on Input 14.Parse simple conditionals: segment, embed, layout, global variables 15.Assign and parse preload_replace variables 16.Parse module and plugin tags 17.Parse PHP on Output 18.Write template to cache file 19.Parse advanced conditionals 20.Process template layouts 21.Process embedded templates 22.Process redirect variable 23.Parse user-defined global variables 24.Parse some standard global variables (separately, in order given): 25.Add CSRF tokens to forms and parse {csrf_token} 26.Parse remaining standard global variables (separately, in order given): 27.Parse alternative syntax forms of the member variables above 28.Parse path variables … Parse segment variables Parse embed variables Parse layout variables Parse date formatting string constants … … Parse advanced conditionals Process template layouts Process embedded templates Process redirect variable … Early Late
  45. @johndwells – GeeUp 2014 PARTIALS Performance https://github.com/andrewfairlie/stash-layouts

  46. @johndwells – GeeUp 2014 PARTIALS Use Cases

  47. @johndwells – GeeUp 2014 PARTIALS <title>

  48. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/entry.html--}! 2. {exp:channel:entries}! 3.

    {embed=“embeds/_head” title=“{title}”}! 4. …! 5. {/exp:channel:entries} 1. {!--_embeds/head.html--}! 2. <title>! 3. {if embed:title}{embed:title} |{/if} {site_name}! 4. </title>
  49. @johndwells – GeeUp 2014 PARTIALS 1. {!--_embeds/head.html--}! 2. {exp:channel:entries limit=“1”

    disable=“…”}! 3. {if no_results}! 4. <title>{site_name}</title>! 5. {/if}! 6. <title>{title} | {site_name}</title>! 7. {exp:channel:entries}
  50. @johndwells – GeeUp 2014 PARTIALS 1. {!--_embeds/head.html--}! 2. {exp:seo_lite use_last_segment=“yes”}

  51. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/entry.html--}! 2. {layout=“_layouts/index”}! 3.

    ! 4. {exp:channel:entries limit=“1”}! 5. {layout:set name=“seo_title” value=“{title}”}! 6. ! 7. …! 8. {/exp:channel:entries}
  52. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <title>{layout:seo_title}</title>

  53. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <title>! 3.

    {if layout:seo_title}{layout:seo_title} |{/if} {site_name}! 4. </title>
  54. @johndwells – GeeUp 2014 PARTIALS Layout “hooks”

  55. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <html>! 3.

    <head>! 4. {layout:head_start}! 5. …! 6. {layout:head_end}! 7. </head>! 8. <body>
  56. @johndwells – GeeUp 2014 PARTIALS Default to 404?

  57. @johndwells – GeeUp 2014 PARTIALS 1. {!--layouts/index.html--}! 2. <head> …

    </head>! 3. <body>! 4. <header> … </header>! 5. <main>! 6. {if layout:contents}! 7. {layout:contents}! 8. {if:else}! 9. Some witty 404 message here! 10. {/if}! 11. </main>! 12. <footer> … </footer>! 13. </body>! 14. </html>
  58. @johndwells – GeeUp 2014 PARTIALS CE Cache

  59. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“layouts/index” title=“Foo”}!

    ! 4. {exp:ce_cache:it}! 5. …! 6. {/exp:ce_cache:it}
  60. @johndwells – GeeUp 2014 PARTIALS 1. {!--blog/index.html--}! 2. {layout=“layouts/index” title=“Foo”}!

    3. ! 4. {layout:set name=“sidebar”}! 5. {exp:ce_cache:it}! 6. …! 7. {/exp:ce_cache:it}! 8. {/layout:set}
  61. @johndwells – GeeUp 2014 PARTIALS Moving Pagination

  62. @johndwells – GeeUp 2014 PARTIALS 1. {exp:channel:entries paginate=“bottom”}! 2. {paginate}!

    3. <p>Page {current_page} of {total_pages} pages! 4. {pagination_links}</p>! 5. {/paginate}! 6. {/exp:channel:entries}
  63. @johndwells – GeeUp 2014 PARTIALS 1. {exp:channel:entries paginate=“bottom”}! 2. {paginate}!

    3. {layout:set name="pagination"}! 4. <p>Page {current_page} of {total_pages} pages! 5. {pagination_links}</p>! 6. {/layout:set}! 7. {/paginate}! 8. {/exp:channel:entries} 1. {layout:pagination}
  64. @johndwells – GeeUp 2014 PARTIALS 1. {exp:channel:entries paginate=“bottom”}! 2. {paginate}!

    3. {previous_page}! 4. {layout:set name=“prev_page” value=“{pagination_url}”}! 5. {/previous_page}! 6. {/paginate}! 7. {/exp:channel:entries} 1. {if layout:prev_page}! 2. <a href=“{prev_page}”>Prev</a>! 3. {if:else}! 4. <a class=“disabled”>Prev</a>! 5. {/if}
  65. @johndwells – GeeUp 2014 PARTIALS Thank you. Partials