A more in-depth look at perch_content

Perhaps the most simple function in Perch’s arsenal is perch_content. This is used to create editable regions within the CMS and like perch_layout, it’s one of those things that perchers use everyday.

It’s super simple but looking under the hood of perch_content will help you understand why perch is faster than other CMSs and provide a base understanding for when we use more advanced techniques like perch_content_custom().

If you’re new to perch, we’d recommend reading the docs on perch_content and checking out this article on Sitepoint which explains the basics of perch_content() with a real-world example which we will continue to use throughout this article.

How perch_content works

Behind the scenes, the data you enter within perch is stored in three different tables within your database:

  • Within perch2_content_items our data is stored in json format (one row per item). So, each item in our carousel, has a row like:
{  
   "_id":"11",
   "image":{  
      "assetID":"5",
      "title":"Placeholder 198",
      "_default":"\/admin\/resources\/placeholder198.jpg",
      "bucket":"default",
      "path":"placeholder198.jpg",
      "size":54571,
      "w":1000,
      "h":666,
      "mime":"image\/jpeg",
      "sizes":{  
         "thumb":{  
            "w":"150",
            "h":"99",
            "target_w":150,
            "target_h":150,
            "density":2,
            "path":"[email protected]",
            "size":9550,
            "mime":"",
            "assetID":"6"
         }
      }
   },
   "alt":"Hillside",
   "title":"The Downs, just north of Brighton"
}
  • Within perch2_content_index each field for each item is stored in a separate row of the database. So one item, creates something like:
+---------+--------+----------+--------+---------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| indexID | itemID | regionID | pageID | itemRev | indexKey | indexValue                                                                                                                                                                                                                                                      |
+---------+--------+----------+--------+---------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|      89 |     12 |       16 |      1 |       3 | image    | /admin/resources/placeholder200.jpg                                                                                                                                                                                                                             |
|      90 |     12 |       16 |      1 |       3 | alt      | Highland Cow                                                                                                                                                                                                                                                    |
|      91 |     12 |       16 |      1 |       3 | title    | Our recent trip to scotland                                                                                                                                                                                                                                     |
|      92 |     12 |       16 |      1 |       3 | _id      | 12                                                                                                                                                                                                                                                              |
|      93 |     12 |       16 |      1 |       3 | _order   | 1001                                                                                                                                                                                                                                                            |
+---------+--------+----------+--------+---------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  • The combined HTML for the entire region is stored in perch2_content_regions ready to be rendered in the browser. Something like:
<ul class="carousel">
    <li><img src="/admin/resources/placeholder198.jpg" alt="Hillside" />
<h2>The Downs, just north of Brighton</h2></li>
    <li><img src="/admin/resources/placeholder200.jpg" alt="Highland Cow" />
<h2>Our recent trip to scotland</h2></li>
</ul>

What does this mean in practice?

  • When you edit content within the CMS, the data is loaded from perch2_content_items. When you click save, you update perch2_content_items, perch_content_index and perch2_content_region.
  • perch_content_index is used for searching and filtering
  • When using perch_content(), you’re accessing the HTML stored in perch2_content_regions
  • When using perch_content_custom() and skip_template, you’re accessing the JSON string from perch2_content_items

In essence data is stored in one place (perch2_content_items), indexed in another (perch2_content_index) and cached in a third (perch2_content_regions).

So why is this important?

Theoretically, perch could be built with just one of these three tables in the database, or at most two (like how Wordpress works with wp_posts and wp_postsmeta).

On the surface, this would feel cleaner. There’s less duplication in the database and you wouldn’t need to republish content when updating templates. However, storing the data this way is in fact a major advantage of working with Perch. The advantages are twofold:

Performance

If you create complex templates, with blocks, regions and repeaters (which you will), without the perch2_content_regions table, the query to render that data in a template would be complex and take time to execute. Storing the rendered HTML in one row of the database, means however complex the template, one row of the database is queried per region. Similarly, storing the content as a json string means if we need our content as an array, that data is still loaded much quicker than if perch relied on extracting the data from perch2_content_index.

Structured Content:

If each item within our carousel was just saved as a string of html then we’d be tied into our current template. Storing the data with arbitrary labels like custom_field1 or date_field2, doesn’t feel much better. Perch takes a different approach. You define the labels of your fields when creating template and then your content is stored alongside those labels in a logical, structured way. You might never need to change your templates or provide your content as a JSON feed or export all your data but knowing your data is stored in a way that at least makes this possible, should give you some peace of mind.


Leave a comment