Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

John D Wells

June 20, 2014
Tweet

Other Decks in Programming

Transcript

  1. @johndwells – GeeUp 2014 PARTIALS Goals • What are “partials”

    • In action with EE 2.8’s {layout=} tag • Common use cases & tricks
  2. @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
  3. @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}
  4. @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}
  5. @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}
  6. @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}
  7. @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}
  8. @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}
  9. @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}
  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 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
  13. @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>
  14. @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>
  15. @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>
  16. @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.
  17. @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.
  18. @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.
  19. @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}
  20. @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}
  21. @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}
  22. @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 :(
  23. @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
  24. @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>
  25. @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}
  26. @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}
  27. @johndwells – GeeUp 2014 PARTIALS 1. {!--_layouts/index.html--}! 2. <title>! 3.

    {if layout:seo_title}{layout:seo_title} |{/if} {site_name}! 4. </title>
  28. @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>
  29. @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>
  30. @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}
  31. @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}
  32. @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}
  33. @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}