Chapter 20

Implement the Back-End Functionality

Summary

This is a deceptively simple step for what amounts to actually building the inner workings of the website. You need to examine the site functionality, break it into manageable iterations, and plan their execution.

Does this Apply?

You’re almost always going to have to do this at some level, but the depth depends on the system. Some systems will be implemented from code and deployed via DevOps, and other systems will be just configured from an interface.

The only time that there’s no backend implementation required would be a highly pre-packaged system for a known, controlled use case (a simple blog, for example).

Narrative

At some point, someone is going to have to coerce a CMS into doing what you need it to do. Most CMSs can publish content in some form out-of-the-box, but they have to be...persuaded to do it in a way that fulfills your requirements.

“Coerce” and "persuade" might seem like weird ways to put it, but the backend development of a CMS is really a process of bending a tool to your needs. Sometimes it’s very close so the influence just needs to be slight, but sometimes it’s wildly off and you need to apply more pressure to get it where you need to go.

Also, there’s a sometimes blurry line between web development and CMS implementation. “Pure” web development would be programming from scratch, rather than building on the base of a CMS as a platform. Think of a CMS as the prefab walls of a structure. Rather than building each wall from nothing but wood and nails, you just need to bolt some existing things together. There’s still quite a bit of development that comes into play, but the CMS should handle a lot of the routine work of processing managed data.

In the sections below, we’ll assume you’re working with a competent web development team, and we’ll outline what that team needs to do to get a CMS to model, aggregate, manage, render, and publish your content.


Model implementation

In an earlier chapter, we discussed your content model, or how to represent your content in a way that maximizes your ability to present and reuse it. Now you have to convert that model into something your CMS can manage.

We’re going to call this a model implementation to separate it from the model in theory. The model implementation is your content model working inside your chosen CMS.

In practical terms, a model implementation is a combination of these things, which are fairly universal:

  • Types: The specific logical types of content. Each content type is a named combination of multiple attributes. For example: “Article”

  • Attributes: A specific piece of managed data. A unique combination of attributes forms a type. For example: “Title” or "Publication Date". Each attribute has a datatype which limits the data which can be stored by it. For example: “Text” or "Date"

  • Validation Rules: A rule further enforces the datatype or the existence of data in a specific attributes. For example: data might be required or a minimum length.

These three things need to be created and configured inside your CMS, usually from an administrative interface or – more commonly, these days – from code.

There are several goals to the model implementation.

  • Descriptiveness: The model implementation needs to describe your content at a level that allows you to manipulate and output it effectively

  • Usability: The model implementation will drive your CMS’s ability to provide your editors with both usable interfaces to manage it and logical relationships

  • Resiliancy: The model implementation needs to keep your content safe and valid, and prevent editors from storing content in an invalid state

The achievement of these goals is not binary – it’s not like your model implementation is “descriptive” or "not descriptive." It’s just gets closer or further away from an ideal. You’ll usually never get all the way there (if it could even be objectively defined).

Why shouldn’t you always attempt full-realization of that ideal? Because every model implementation is a balance between complexity and flexibility. A key point when implementing your model in a CMS is deciding how far to take it. You can handle every possible edge case and theoretical situation, but the result might be too complex for your editors to work with. The stricter your model implementation becomes, the more friction it introduces to the editorial process. You need to decide how strict this needs to be.

Additionally, your CMS imposes limits. And sometimes they’re unfortunately arbitrary and final. In a theoretical model, anything is possible. However, CMSs have specific featuresets around content modeling – they’ll no-doubt support some aspects, but might struggle with others.

Your ability to accurately represent your model depends on the modeling capabilities of your CMS, but also on the creativity and experience of your development team. Given enough experience with a specific CMS, a developer will learn with all the traps are. There are patterns to modeling, so any problems you have are likely to come up multiple times. Any developer experienced in a CMS should be able to look at your requirements and mentally formulate solutions to 90% of them, while only some of the more advanced problems might take from prototyping and trial-and-error.

However, sometimes you just can’t wrap a CMS around your model requirements.

For example:

  • Your model requires that an Article object is linked to an Author object. This is supported, so a reader can see who wrote an article, then click on their name to be taken to their page. However, your CMS doesn’t consider this link to be bi-directional, so it’s not possible to find Article objects that have a particular content object (your Author object) with links to it.

  • Your model requires a Meeting object to have sub-objects for Topics. Each Topic is also a content object. To do this, you need to connect a Topic to a Meeting in a parent-child model. However, your CMS doesn’t have a content tree that would allow this, nor does it allow nested objects. You can link a Topic to a Meeting, but someone else could link another Meeting to the same Topic (not allowed by the model), and it doesn’t stop the Meeting from being deleted and “orphaning” a bunch of Topics (also verboten).

These examples might seem weirdly specific, but they’re accurate examples of where content models run into problems. Even the simplest modern CMS allows the definition of structured types – that’s the easy part. The problems crop up at the edges, where you had an idea that seemed simple in theory but becomes infuriating in practice when you simply can’t wrap your CMS around it. You try to “fit” your idea in multiple ways, but the CMS seemingly thwarts you at every turn.

Model implementation is a process of concessions. Consider our second example from above, and here are some ways you might get around those limitations.

  • You might decide that someone could link a Topic to two Meetings, but that’s just a thing you’re gonna have to live with. Maybe you educate your editors to just not do this, or create a report that shows you when this happens, so you can correct it.

  • You might limit the deletion of Meeting objects by permissions, restricting it to administrators (or even just a single master editor) who knows better than to orphan Topic objects.

  • You might have a developer create some code to unlink a Topic from a Meeting when it’s linked to a different meeting, or automatically delete all related Topics when a Meeting is deleted.

The reality of your CMS’s capabilities can be a wet blanket, but it’s something most projects encounter at some point. The flexibility of a theoretical model often clashes with reality.

Editorial Experience

One of the goals of the model implementation we explained above was “descriptiveness.” You need to describe your content to your CMS.

Let’s take a trip into the Theater of the Absurd. Imagine sitting at a whiteboard with your CMS, and drawing it out so your CMS understands what the different types are, how they work, and why this matters. Consider this imaginary conversation with your CMS:

You: Okay, now an Article has a Published Date…

CMS: I’ll show a date picker for it, but does it need a time?

You: No. No time.

CMS: [takes notes] Okay, I won’t show the time selector then. Can the date be in the future?

You: No.

CMS: [furiously scribbling notes] Okay, I’ll prevent them from entering a future date.

As you describe your content more carefully, the CMS can use aspects of its UI to force or coerce editors to enter correct data.

  • Data Coercion: The usage of editorial elements to prevent the entering of invalid data. For example, the usage of a date picker, or the elimination of the time selector. By doing these things, the UI is actively preventing invalid data from being entered. There is just no other way.

  • Data Validation: Sometimes, an editor can enter invalid data, but the CMS can prevent it from being saved or stored by validating the Published Date to be sure it’s in the past. If it fails validation, the CMS can show an error message and require the editor to change it.

Let’s continue the conversation:

You: I want them to be able to format this text.

CMS: I can display a rich text editor. Can they do anything they want?

You: No, just bold, italics, and linking. No tables or anything like that.

CMS: No worries. We’ll only show them buttons they can use.

Limiting or “neutering” rich text editors is a critical aspect of editorial experience. As a general rule, only show editors things they can use.

You: Okay, now if they don’t enter an “SEO Title,” we’re just going to use the regular title.

CMS: Got it. We should tell them that. I can include a message under the field so they know.

Accurate labeling of form fields is critical, both in the simple label and any extended help text. Every field should have clear instructions of how it relates to the model.

You: This is a lot of fields. This might be confusing.

CMS: Tell me how they relate. I’ll put them in tabs.

The simple grouping of fields under tabs or collapsible headings can help enormously in limiting the cognitive overhead of perceiving a giant page of form fields.

In each case above, we’re describing our content model more and more, which is enabling our CMS to make our editors’ experience better and better. Most systems will have these features built-in, but they logically require an understanding of the model to be manifested – a CMS can’t just decide how to group fields; you need to tell it. Generally speaking, the more you describe your model, the better the experience can be.

Projects tend to concentrate on the visitor experience, and gloss over editorial experience, to their detriment. Happy editors make better content, and a shocking number of CMS re-implementation projects have started from the same sentence: “Our editors hate using our CMS.”

Cater to your editors. Implement your content model at a level that allows the CMS to help them. The happier they are, the better your content will be, and the longer your CMS implementation will last.


Aggregations

As we discussed in the chapter on content modeling, content objects don’t exist in a vacuum. They usually have to be organized into larger structures in order to provide some value.

Every CMS will offer a toolkit of features to manifest your logical model aggregations. One of the key skills in working with any CMS is knowing what these aggregations are, and their relative advantages and drawbacks, so you know when to use one over the other.

Some common aggregation tools:

  • A Content Tree: A very common pattern is a “tree” of content, where you have a "root" object with a hierarchy of descendants below it. Every object is a child of another object, and might have one or more children of its own. This is a very common way to organize content and overlays naturally on navigation and website organization. For many systems, this is the main organizational method for content.

  • Folders: Occasionally a system will organize content by containers, often visualized as “folders” to piggyback on the visual model of most operating systems. In a way, this is also a parent-child structure, but parents can only be of a specific type (the folder).

  • Menus or Collections: Most systems will also have some arbitrary method of organizing content into serial lists or hierarchical menus. In some cases these are literally meant to be web menus (sometimes with pre-built HTML ), in others cases they’re just meant to structure content so it can be accessed in some group via code or from templating. A key point here is ordering: both these aggregation methods allow you to put content in an explicit order.

  • Tags or Categories: As we discussed in our chapter on information architecture, it’s also common for some method of tagging or categorizing content. The two methods are very similar, but categories are usually created in advance by someone responsible for maintaining the organization structure, and they can often be organized into a tree. Conversely, tags tend to be ad hoc, so editors can make them up on-the-fly. Unlike menus/collections, content in tags or categories are just in a big “bucket,” with no ordering or further organization.

The differences between aggregation methods can be subtle, and there’s often a lot of overlap. A hierarchical menu structure is very similar to a content tree. And tagging or categorizing content can seem very similar to putting content in a collection.

A sometimes frustrating aspect of developing with any CMS is learning that there can easily be a dozen different ways to achieve a particular goal, especially with aggregations. Doing it with Aggregation Type X might give you a few advantages, while Aggregation Type Y gives you a few different advantages. But both methods technically work at some level. Neither is wrong, they just work in different ways.

The choice to use X over Y can come down to some very subtle factors, and tragically, these factors might not surface until after the system launches and is in production. Months down the road, your editors might be frustrated or have come up with some particular use case that a certain aggregation doesn’t handle well, and to fix it, you have to back out large portions of the system and re-work them using a different aggregation method.

Your developers will use content aggregations to build out the basic framework of your site. Your content model, even when turned into a concrete model implementation, is still just theoretical until it starts filling up with content and those building blocks are stacked, via aggregation methods, into some sort of framework to form a larger domain of information.

The actual aggregations that come out of this process might be used to:

  • Form primary navigation (ex: the main, overhead navigation, or a “super footer”)

  • Create localized, sectional navigation (ex: “In this Section”, or "Our Products")

  • Create index pages, or lists of content, of content (ex: “Latest News”)

  • Create topic-based indices of content (ex: “Articles About China” or "Related Content")

Content Rough-In

Even once the model implementation is in place, the content is still very theoretical. A model implementation is a framework or container or content, but there’s nothing in it yet.

Your developers will usually have to go through some explicit stage of “rough-in” where they add some content to the system. They’ll need to do this both to test the model implementation – what works; what doesn’t work – and to confirm that aggregations work as expected. It’s hard to figure out if a particular aggregation will work for the main navigation unless you create it and work with it.

Content rough-in is not migration. You might test some migration methods by moving some content and using that (highly recommended, in fact; nothing works like real content), but often a developer will just enter some “junk” content to provide some building blocks to the system.

When the model implementation is in place, the aggregation methods are created, and content rough-in has provided something to put in structures to create the basic “shell” of a website – that’s when you can really begin to see how things come together.


Templating and Output

In the prior chapter, we discussed front-end development and gave some examples of HTML. What we didn’t explain is how your content comes to be mixed in with that HTML. Static HTML doesn’t help – we need HTML that changes to represent the different content in our CMS.

This happens through some process of templating, whereby static HTML is mixed with dynamic content to form output. A template is text which is a starting point for output – it’s usually a mixture of HTML and special programming code that injects data from a content object to generate a specific output. Apply Content Object A and you get a certain output; apply Content Object B and you get a different output.

Here’s a sample of what a template might look like:


<h1>{{ article.title }}</h1>

<p class="date">Published on {{ article.date }}</p>

<p class="byline">Written by {{ article.author }}</p>

<div class="body">

{{ article.body }}

</div>

Those text snippets between the double brackets ("{{" and "}}") are called tokens. They mean, roughly, “Insert some content here.” Clearly, the title is going in the heading at the top, following by paragraphs for the date and the author, and then the article body below that.

Token replacement is the most basic feature of templating. Without token replacement, you don’t really have a template at all.

Another common feature is output filtering, whereby content can be output in different formats. For instance, say we wanted our title in ALL CAPS. We might have a filter for it, like this:


<h1>{{ article.title | caps }}</h1>

That vertical bar is called a pipe, and it’s historically been used to apply functions to input. In this case, we’re saying, apply the function caps to whatever is in the title. In this case, the function caps is assumed to take text and turn it into all capital letters.

In some cases, filters can be configured with arguments.


<p>Published on {{ article.date | format:"yyyy-mm-dd" }}</p>

In this example, you’re using a filter called format to output a date in a specific way. This is helpful, since the date is stored in a universal format, and you might want it output in different ways in different places in your website. You can use a filter to output the same date differently.

Another helpful feature is looping. Your template might have a piece of data representing a collection of objects, and it can repeat a section multiple times.


<ul>

{{ foreach article in articles }}

<li>{{ article.title }}</li>

{{ endforeach }}

</ul>

In this case, articles represents a group of article objects. The above code will create a bulleted list showing one bullet for each article (the ’li’ tag, which means “list item”), whether it be one article, two articles, or 300 articles.

Finally, another helpful feature of templating is conditionals, where you can make decisions about whether or not to do something.


{{ if article.author not empty  }}

<p>Written by {{ article.author }}</p>

{{ endif }}

In this case, the paragraph element and label would only be output if the author contained a value.

These four constructs – token replacement, filtering, looping, and conditionals – are the basis for most every templating language. Using these things, a development can take content data and form HTML output.

Request Mapping and The Operative Content

We discussed the request-response model of the web in a few prior chapters. Remember that a web content management system responds to requests. Someone inputs a URL in their browser and some HTML is returned.

In most CMSs, specific content objects get assigned URLs when they’re created. The URLs are often based on the type of content, or where the content sits in a content tree (each object gets a segment, and the segments of all the ancestors back to the root object form the URL).

Regardless of method, content objects which are intended to be directly addressed by a URL know what URL they should respond to.

Given this, here’s how the request-response model plays out for a CMS.

  1. A request comes into the server.

  2. The CMS intercepts this request and locates the content object to which the request is directed.

  3. The CMS determines what template should be used.

  4. The CMS combines the content object and template (review the examples above) to generate HTML output.

  5. The CMS sends the output in the response.

The process in steps 2, 3, and 4 is quite common in CMS architecture: map the URL to a content object, select a template, and execute the template against that content. The content object which is found in step #2 is known as the operative content object, meaning it’s the content object on which the request is “operating.”

For example:

  1. The URL /news/tax-increase-is-coming is requested.

  2. The CMS intercepts that, searches its repository, and locates News Article #437 as having that URL.

  3. Checking its configuration, the CMS finds that News Article objects used the template in a file called news-article.tpl.

  4. The CMS executes news-article.tpl with News Article #437 as the operative content object and gets a bunch of HTML in return.

  5. The CMS sends that HTML as the response.

In most systems, there is always an operative content object. It might be a news article, a text page, a news article listing page – whatever. But there is usually a central, operative object on which each request is operating.

We noted in step #3 that the CMS needs to find a template. What template does it use? Usually, there’s a single template per content type – so News Articles have one template, Products have another template, etc. This makes sense, because templates need to know what type of content they’re operating against. You can’t execute the Author content for a Product, for instance. You have to know what data you have before you can output it.

Some systems have more complicated templating rules. It might default to a template per type, but there might be situations where you can specify a custom template for a particular object, for example. So all News Articles use the same template, except for News Article #437, which uses a special template, for whatever reason.

Template Languages

In the examples above, we were using a fake templating language, roughly based on several actual languages. Thankfully, template languages exist independently from CMSs – they’re usually their own independent projects, CMSs just choose to use or support particular languages. This means that knowledge of a particular template language can span different CMSs.

Remember our discussion of the “technology stack” from in the hosting chapter, and remember that every CMS is written in an underlying programming language. Templates are "sub-languages" within those, that run “inside” those languages.

Here are some common languages for various underlying languages.

  • .NET: Razor is very common, and is the default for most projects. Other languages are Fluid and Scriban.

  • PHP: Twig is the most common language. Smarty is an older language, but still popular. And some systems simply use PHP itself (discussed more below).

  • Java: Freemarker and Velocity

  • There are also templating languages that have versions for multiple programming languages, like Mustache

As noted, some PHP systems use PHP directly to generate output, because PHP itself started life as a web templating language then grew into a fuller programming language. You can also do this in any other language – HTML is just text, and any programming language can generate text – so why use a separate templating language at all?

Several reasons –

  • Template languages are meant to be safer than the full programming language. Front-end developers often work in templates, and in many cases they shouldn’t have access to the full power of the underlying language because a mistake there could break the entire website. Template languages are meant to fail safely, and not break anything other than their own, immediate output.

  • The needs of templates are usually simpler than more foundational tasks handled by the full language. There are some complicated issues in programming that just don’t need to be handled with templates. Template languages are designed to limit power and therefore complication. A developer should be able to perform simple token replacement, for example, with very little training.

  • Generating output with a full programming language would be crude and unpleasant in most cases, as programming languages aren’t optimized to generate HTML. Template languages are designed to easily intermix between HTML code and provide tools specifically to ease output generation (filters, for example).

An excellent summation of this philosophy is provided by the Wikipedia page for the Razor language:

The idea behind Razor is to provide an optimized syntax for HTML generation using a code-focused templating approach, with minimal transition between HTML and code. The design reduces the number of characters and keystrokes, and enables a more fluid coding workflow by not requiring explicitly denoted server blocks within the HTML code

That approach is largely true of template languages as a genre. Templating is considered a special use case, therefore special languages have developed around it.

There are raging, philosophical debates about how much power templates should have. Should they only be able to use the data given to them? Or should they be able to “reach outside” themselves and drag in more data? Who controls what information a template is allow to operate on? How much logic should templates be allowed to implement?

Many developers like to keep their templates “dumb,” because too much code inside templates just splits logic between programming languages. If there’s a problem, now you have two places to look for it. Other developers don’t really care, and just put logic wherever it suits them.

There’s no set answer. It depends on the CMS, or – more commonly – on the opinion of the senior-most developer on the implementation team. They tend to set the philosophical attitude of the group, and their opinion will dictate standards.


Other Development Tasks

So far, the back-end developer has implemented the content model, designed and created the necessary content aggregations, roughed-in the content, and templated the output. This is the backbone of a CMS implementation. The bulk of the work exists in those tasks.

However, depending on your requirements, there are quite a few other details to be handled.

  • Users, Groups, and Permissions: Everyone accesses a CMS in the form of a user (even if it’s a common user like “Anonymous”). Those users need to be created, organized into groups for manageability, and have permissions assigned. The goal is to protect your content, and protect users from themselves – no one should accidentally be able to do something they didn’t intend.

  • Workflows and Content Operations: If the headcount of your editorial team is larger than one, then there might be a larger process to get content published – so-called content operations. This might involve making sure content preview works the way it should, and workflows and approval chains are in place to ensure more than one set of eyes looks at content before the public does.

  • Localization: Many organizations publish content in more than one language. Your CMS will need to be configured to allow content translations in specific languages, and you’ll need to decide how to detect language requests , and perhaps fallback through multiple language options for the best match. Templating might need to change as well – some languages are vertical, some are right-to-left, some are longer than others , etc.

  • Marketing Tools: One of the goals for a new CMS might have been to use some new-fangled marketing tools, like personalization and A/B testing. While these are more content challenges than technical challenges, they will still need to be enabled and configured.

  • Page Composition: Some pages on your site will be composed rather than templated, which means editors create the pages by visually dragging managed components around a page surface. Special pages or templates will usually need to be created to support this. These pages often have zones or regions into which components can be placed and ordered.

  • Search: Sometimes search just works, but there are often lots of different configuration options available. You might want to hide some content from search, or boost other content. You might need to configure options like faceting or methods of finding related content.

  • Reporting: Editors often need reporting about their content, ranging from simple usage analytics, to quality checking and productivity reports – what images are no longer being used, where does a certain term appear in the content, how many content objects has each editor touched in the last 30 days, etc.

  • Archiving: What happens to content when it’s not needed anymore? Does it get hidden? Deleted? Archived? What do those terms even mean in the context of this CMS? You need to plan for the entire lifecycle of content, and your CMS might need to be configured to handle obsolete content in a specific way. This includes content versions – how many versions of content should you retain, extended back how far in the past?

  • Integration: As we discussed in an earlier chapter, your CMS might need to talk to other systems to provide content or functionality. These integrations need to be developed, or installed and configured.

  • Forms: Webforms are handled differently depend on the system – in some, they’re a development task, while in others, they’re managed as content, purely by editors


It’s hard to generalize about implementing the backend of a content-managed website, since the tasks and challenges different wildly based on requirements. What we’ve tried to do here is present the bare minimum of what would have to be done – a common backbone of work:

  1. Model Implementation

  2. Aggregation Implementation

  3. Content Rough-In

  4. Templating

We can state with some confidence that those four things have to be done in all implementations. Beyond that, every CMS and every implementation will be done a little differently.

Inputs and Outputs

The input to this process is almost the sum total of everything you’ve done so far. You’ll need your requirements, your integrations, your selected CMS, and at some point, your front-end implementation. The output is a running CMS implementation, ready for deployment.

The Big Picture

Back-end and front-end implementations often run in parallel. There’s a lot that a back-end team can do before they need the front-end team’s output for templating. And a lot of templating is trial-and-error. The two teams will need to communicate frequently, and go back-and-forth quite a bit to make some things work.

Back-end implementation is also often being done at the same time as content migration, which we’ll talk about later.

Staffing

You need a server-side development team, well-versed in your selected CMS and the underlying technology stack on which it runs.