-
Notifications
You must be signed in to change notification settings - Fork 20
Template inheritance
Mark Croxton edited this page Jun 20, 2013
·
37 revisions
Essentially this pattern allows you to extend parent view and viewModel templates with child templates loaded on the fly. Views contain block elements that render default content.
In the following example we're using a custom field to optionally choose a 'widget' (child viewModel) for a page content. The child VM extends the parent VM and can load it's own partial layout and overload fields in the parent view.
work
index.html
layouts
standard.html
viewmodels
page_vm.html
projects_vm.html
partials
project_list.html
project_detail.html
Loads the primary viewModel, compiles and caches the rendered templates as a variable, using the page URI as the context.
{stash:embed
context="@URI"
name="page_vm"
file_name="viewmodels:page_vm"
parse_stage="both"
stash:_status="open"
stash:_channel="pages"
stash:_layout="standard"
}
{stash:embed context="layouts" name="{stash:_layout}"}
{!-- capture entry data --}
{exp:channel:entries
channel="{stash:_channel}"
status="{stash:_status}"
limit="1"
disable="member_data|pagination|categories"
{if segment_2} require_entry="yes"{/if}
}
{if no_results}
{redirect="site/404"}
{/if}
{!-- standard entry fields --}
{exp:stash:set type="snippet"}
{stash:pg_title}{title}{/exp:low_replace}{/stash:pg_title}
{stash:pg_entry_id}{entry_id}{/stash:pg_entry_id}
{stash:pg_url_title}{url_title}{/stash:pg_url_title}
{/exp:stash:set}
{!-- custom entry fields --}
{exp:stash:set type="snippet"}
{stash:pg_intro}{page_intro}{/stash:pg_intro}
{stash:pg_body}{page_body}{/stash:pg_body}
{/exp:stash:set}
{!-- load a widget (child viewModel)? --}
{exp:switchee variable="{page_widget}" parse="inward"}
{case value="#^S+#"}
{!-- load the associated viewModel for the widget --}
{exp:stash:embed
context="viewmodels"
name="{page_widget}_vm"
process="inline"
replace="yes"
}
{/case}
{/exp:switchee}
{/exp:channel:entries}
{exp:switchee variable="{segment_3}" parse="inward"}
{!-- project listing --}
{case value=""}
{!-- load the project_list layout into the pg_content block --}
{exp:stash:set name="pg_content"}{exp:stash:embed:partials:project_list}{/exp:stash:set}
{exp:stash:set_list
name="projects"
parse_tags="yes"
}
{exp:channel:entries
channel="projects"
status="open"
disable="member_data|pagination|categories"
dynamic="off"
}
{stash:project_title}{title}{/stash:project_title}
{stash:project_url_title}{url_title}{/stash:project_url_title}
{/exp:channel:entries}
{/exp:stash:set_list}
{/case}
{!-- project detail --}
{case default="yes"}
{!-- load the project_detail layout into the pg_content block --}
{exp:stash:set name="pg_content"}{exp:stash:embed:partials:project_detail}{/exp:stash:set}
{!-- get project data --}
{exp:channel:entries
channel="projects"
status="{stash:_status}"
limit="1"
disable="member_data|pagination|categories"
url_title="{segment_3}"
dynamic="off"
require_entry="yes"
}
{if switchee_no_results}
{redirect="site/404"}
{/if}
{exp:stash:set type="snippet"}
{!-- override the heading in the main layout --}
{stash:pg_title}{title}{/stash:pg_title}
{!-- capture project custom fields for use in the project_detail partial --}
{stash:project_image}{project_image}{/stash:project_image}
{/exp:stash:set}
{/exp:channel:entries}
{!-- prev/next entry links --}
{exp:channel:next_entry
channel="projects"
status="{stash:_status}"
url_title="{segment_3}"
parse="inward"
}
{exp:stash:set name="project_next_url" type="snippet"}{url_title}{/exp:stash:set}
{/exp:channel:next_entry}
{exp:channel:prev_entry
channel="projects"
status="{stash:_status}"
url_title="{segment_3}"
parse="inward"
}
{exp:stash:set name="project_prev_url" type="snippet"}{url_title}{/exp:stash:set}
{/exp:channel:prev_entry}
{/case}
{/exp:switchee}
<!DOCTYPE html>
<html>
{sn_head}
<body>
<h1>{pg_title}</h1>
<div class="content">
{exp:stash:block name="pg_content"}
{if pg_intro}<p class="intro">{pg_intro}</p>{/if}
{pg_body}
{/exp:stash:block}
</div>
{sn_footer}
</body>
</html>
<ul class="list list--projects">
{exp:stash:get_list name="projects"}
<li><a href="/{segment_1}/{segment_2}/{project_url_title}">{project_title}</a></li>
{/exp:stash:get_list}
</ul>
<img src="{project_image}" alt="">
<a href="{project_prev}">Previous</a> | <a href="{project_next}">Next</a>
Getting started
Using Stash
Using Mustash
- Mustash
- Installing Mustash
- Managing variables
- Managing bundles
- Cache-breaking rules
- Mustash plugins
- Mustash Varnish plugin
- Mustash plugin development
- Mustash API
Template design patterns
Tag reference
- {exp:stash:set}
- {exp:stash:get}
- {exp:stash:block}
- {exp:stash:set_value}
- {exp:stash:append}
- {exp:stash:append_value}
- {exp:stash:prepend}
- {exp:stash:prepend_value}
- {exp:stash:copy}
- {exp:stash:context}
- {exp:stash:is_empty}
- {exp:stash:not_empty}
- {exp:stash:set_list}
- {exp:stash:get_list}
- {exp:stash:append_list}
- {exp:stash:prepend_list}
- {exp:stash:split_list}
- {exp:stash:join_lists}
- {exp:stash:list_count}
- {exp:stash:unset}
- {exp:stash:flush_cache}
- {exp:stash:bundle}
- {stash:embed}
- {exp:stash:extend}
- {exp:stash:parse}
- {exp:stash:cache}
- {exp:stash:static}
- {exp:stash:finish}
- {exp:stash:not_found}
- Short tag syntax
- Using Stash methods in your own add-ons