Use Attributes to Customise Pages

Sometimes it’s nice to be able to control things at the page level for any pages. It might be something you don’t need to add very often and isn’t “turned on” any page by default, but you want to have the option to do it straight from the control panel. Rather than including an optional region on every master page (crowding the region list and making your editor feel anxious about leaving them empty), you can rely on page attributes.

What are Page Attributes?

Page attributes are a way of storing editable content at the page level. This could be anything from meta tag descriptions for SEO, through to options to control what class gets added to the body tag for your CSS to use.

The default attributes template can be found in templates/pages/attributes/default.html. It uses template includes to include templates from inside it. By default it includes the seo.html template for metadata:

<perch:template path="seo" />

You could do the same thing to add sections to your page attributes edit form: create section.html template and include it in default.html.

Note that if you are using perch_page_attributes() to include metadata in <head>, you will need to modify that to only output the seo data:

perch_page_attributes([
    'template' => 'seo.html'
]);

Let’s go through some examples.

Message bar

Setting an attention seeking or a warning message at the page level can be useful (depending on your use case). If you want it to appear gloabally on all pages, you would use a shared region.

What we want here is to be able to go to any page, go to the Details tab and type in a message to be displayed on that particular page.

Let’s say you have a website that has event listing and a podcast show: You may want to add a message to the event listing page saying “We’re not holding any events until March”, but also would like to add a message at the top of the podcast listing page saying “We have re-uploaded episode #74 in better quality”.

Create a new template attention.html and place it in the attributes folder. We are using <perch:if> conditional tags here. If the field is empty, nothing will be output.

<perch:if exists="attention_msg">
<div class="message-bar">
    <perch:pages id="attention_msg" type="text" label="Attention Message" divider-before="Other"/>
</div>
</perch:if>

Include the new template in the default attributes template:

<perch:template path="seo" />
<perch:template path="attention" />

Display it on your master pages:

perch_page_attributes([
    'template' => 'attention.html'
]);

Restrict access

Let’s do something slightly more complex.

If your website is live and you are having issues on a page or going to deploy changes that you fear might affect a page on your live server, it would be handy to be able to temporairly restrict access to that particular page to you only.

So let’s add some sort of “development mode” at the page level where when enabled only you can access the page and all other visitors get directed to another page.

Create a new template dev.html and place it in the attributes folder. Add a checkbox field to the template.

<perch:pages id="dev_mode" type="checkbox" label="Development Mode" divider-before="Development"/>

Include the new template to the default attributes template:

<perch:template path="seo" />
<perch:template path="dev" />

Now if you go to your page in the control panel and click on the Details tab, you’ll find a new field at the bottom under ‘Development’.

At the top of all your master pages, you can check whether the checkbox field is checked and act accordingly:

// Get the value of the checkbox field
$dev_mode = perch_page_attributes([
    'template' => 'dev.html'
], true);

// Attempt to get the currently logged in user (Perch control panel)
$Users = new PerchUsers;
$CurrentUser = $Users->get_current_user();

// Redirect visitors when in development mode and if the visitor isn't a logged in user
if($dev_mode && (!is_object($CurrentUser) || !$CurrentUser->logged_in())) {
    PerchSystem::redirect('https://example.com/');
}

Put it directly in default

If you are only adding a single field, it makes sense to add it straight to default.html instead of creating a separate template:

<perch:template path="seo" />
<perch:pages id="dev_mode" type="checkbox" label="Development Mode" suppress="true" divider-before="Development"/>

You then need to use the singular perch_page_attribute() which you can use to get a single attribute.

$dev_mode = perch_page_attribute('dev_mode', [], true);

Conclusion

Page attributes can be extremely useful and an elegant way to control and customise things at the page level. It makes sense to use them when you want some options for controlling or customising most (if not all) pages. You can use it to add optional content (like the message bar) or to trigger some behaviour (like restricting access).

The examples above are just examples. Try to grasp the concept so you can apply it to work for your case.

link