Drafting at the Page Level

Perch has built-in drafting and revision system for content regions, regions items and Collection items. However, there is no built-in “drafting” system for pages as a whole (at time of writing - as of Perch 3.1)

This is possibly because content doesn’t live in a page; it may be in a region, a Collection, a Shop product, etc. So certainly a revision system at the page level doesn’t make sense, but being able to set a page as a “draft” before making it live can still be useful.

This can be particularly useful when there are multiple teams managing the website and/or pages have to be approved by someone. It gives editors the chance to create content knowing the page is not publicly accessible.

Page Attributes

As discussed in the post Use Attributes to Customise Pages, when you need to customise/control things at the page level Page Attributes are your friend.

Add the following field to your page attributes template templates/pages/attributes/default.html:

<perch:pages id="status" type="select" label="Status" options="Draft|draft,Published|published">

Controlling Access

Now we need to control who can access a page that does not have the status of “published”. Let’s restrict “draft” pages to users who are logged into Perch’s control panel and send everyone else to the 404 page.

Add the following to the top of all your pages. If you’re using regular Perch and not Runway, you should add this directly after the Perch runtime include.

// check if user logged in control panel
$logged_in = false;
$Users = new PerchUsers;
$CurrentUser = $Users->get_current_user();
if (is_object($CurrentUser) && $CurrentUser->logged_in()) {
  $logged_in = true;
}

// get the page status
$page_status = perch_page_attribute('status', [], true);

if($page_status != 'published' && !$logged_in) {
  PerchSystem::redirect('/errors/404');
}

Exclude Drafts Elsewhere

You should exclude draft pages from appearing in places like the site’s sitemap. Assuming you are using perch_pages_navigation() to add pages to your sitemap, you can use Perch’s conditional tags to exclude draft pages in the template:

<perch:if id="status" value="published">
<url>
    <loc>https://www.example.com<perch:pages id="pagePath" /></loc>
    <changefreq>monthly</changefreq>
    <priority>1.00</priority>
</url>
</perch:if>

Existing Sites

If you want to implement this into existing sites, make sure you add the page attribute field status and mark live pages as “published” before adding the PHP code at the top of your pages otherwise the whole site would direct to your 404 page.

link