April 26, 2017
Maintainable Perch Templates
Some of your Perch templates might be quite long. For example, a typical product template (using the Perch Shop app) has 20+ Perch tags: the default tags you need to keep and the custom tags you may add.
When you start mixing your HTML with so many Perch tags, it can get a little
messy. Firstly, there can be a lot in there: you have Perch tags that contain
many attributes that improve your edit form and have no impact on the HTML
rendering such as help
,
size
and
divider-before
as well as other necessary
attributes such as id
,
type
and
label
. Then you got to think about the
order of the fields on the edit form (which can be very different from what
you need for your markup) so you start adding
order
attributes to these tags.
1<perch:shop 2 id="short_desc" 3 type="textarea" 4 label="Short Description" 5 markdown="true" 6 editor="markitup" 7 size="s" 8 help="This is displayed above the product options. It should be a concise description that highlights the product's best features" 9 order="4"10 divider-before="Product Details"11/>
In small templates, it doesn’t feel like much. You can see where everything is and edit whatever you want quickly. However, in a big template things can get lost especially if you are reviewing a template you had written a while ago.
What you can do
Generally, you need a Perch template for two tasks:
To create (and edit) content/data for an item (product, blog post, etc)
To retrieve content and display it on a page
Perch is very flexible, so you can have a template to create the content and use another template to display it on a page. You can create some separation here to make things more manageable, more maintainable.
Example:
The following Perch Shop function uses the default product template (perch/template/shop/products/product.html):
1perch_shop_product('my-product');
By removing all your markup from the default product template (leaving Perch tags only), it will be easier to manage your edit form. You can move tags around as you wish and not worry about using any order attributes. You can focus on making the edit form more logical and user-friendly for your editors/clients without any HTML in your way. The template will be a lot easier to edit in the future.
As for your markup, create another template just for your frontend (HTML output). You can give it a different name and place it in the same directory as the default template, but I prefer to create a sub-directory named frontend and place the file there.
At render time, we always need the id and the type attributes.
You will still need Perch tags inside your frontend template, but you can delete all the attributes from them except the id and type attributes (always needed).
You can delete all the help
and
note-before
attributes (that may have
long explanations), order
and
divider-before
that are also purely for
the edit form. You can also delete any Perch tags you don't need in your
frontend template rather than using the
suppress
attribute to hide them.
You'll end up with very short Perch tags and potentially fewer of them. Now you can scan through your markup much faster.
Below is a Perch tag with the ID of
short_desc
. To put into context: it is a
short description of a product. On the product page the editor can add a short
description and a detailed one. So by adding the
help
attribute we can give the editors
some tips to differentiate between the two fields.
1<!-- short_desc in template/shop/products/product.html (the template used for the edit form) --> 2<perch:shop 3 id="short_desc" 4 type="textarea" 5 label="Short Description" 6 editor="markitup" 7 markdown="true" 8 size="s" 9 help="This is displayed above the product options. It should be a concise description that highlights the product's best features"10 divider-before="Product Details"11/>12 13<!-- short_desc in template/shop/products/frontend/product.html (the template used for front-end) -->14<perch:shop id="short_desc" type="textarea" />
Don't forget to edit your perch_shop_product function:
1perch_shop_product('my-product', [2 'template' => 'frontend/product.html'3]);