As we began planning the new Marketpath CMS, we had two primary goals:
These were two roadblocks in the old web management system that truly hindered development and our ability to build unique interactive sites.
Goal #1 is an ongoing challenge. Every new feature we build into the system has the capability to disrupt this goal. We build in default output HTML for every object, but we have to also build a way for that to be overridden. So far, we've accomplished this but not without some good old fashioned office throwdowns.
Goal #2 took a lot of research and planning. There are many different templating languages available but we chose Shopify's Liquid Template Language, because it provides a robust processing engine with if/else conditionals, for loops, mapping, filters, and much more. Specifically, and since we are primarily .Net developers, we use the .Net port of Liquid called DotLiquid. This allows creation of custom methods, filters, objects, collections, and more. To this day, we're still very happy with this selection and have expanded on it a great deal. Check out our Liquid reference documentation for more.
Liquid can be used by front end (UX) developers who aren't familiar with backend programming lanuages. The code can be placed right inside standard HTML and reference fields and objects of the page. Below is an example if/else statement that checks if there is a value in the summary field and displays it if it does.
{% if entity.summary_html.is_valid %} <div class="summary">{{ entity.summary_html }}</div> {% else %} <div class="summary">No Summary</div> {% endif %}
In the code below, I grab the 5 newest articles that have the tag "News" and display those using a for loop.
{% articles var news = tag:"News" limit:5 sort_by:"post_date" sort_direction:"desc" %} {% for item in news %} <div class="title">{{ item.title }}</div> <div class="content">{{ item.content_html }}</div> {% endfor %}
Liquid allows you to include partial templates so you don't have to repeat code throughout your site. For the example below, assume this is a page template for the contact page. There are three partial template included: one for the header, one for the page's banner images, and one for the footer. The banner-images partial is also passed a value for its bimages variable from the current entity's (page's) image list. If we need to update how the banner functions, we can simply update the banner-images partial template and it will be automatically updated throughout the entire site. The same goes for the header and footer partial templates.
{% include "header" %} {% include "banner-images" bimages:entity.banner_images.items %} <div class="contact-map">.... SHOW MAP </div> <div class="contact-address">.... SHOW ADDRESS </div> {% include "footer" %}
I've mentioned entity a few times in this post. That refers to the object with the current URL that is being rendered. Entities in Marketpath CMS can be Articles, Blog Posts, Calendar Entries, Tags, etc. If you edit and provide a URL for an object, then we refer to it generically in the template as entity, regardless of it's actual type.
Every entity type in the system has pre-defined properties but can be extended by adding additional fields to templates. In the contact template example I showed above, I might add longitude and latitude fields that can be used in a Google map. I access these with the code "{{ entity.latitude }}" and as shown below in the code. You may also notice I pulled in a custom site setting to set the Google Maps API key.
<div id="map"></div> <script> var map; function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: {lat: {{ entity.latitude }}, lng: {{ entity.longitude }}}, zoom: 8 }); } </script> <script src="https://maps.googleapis.com/maps/api/js?key={{ site.google_maps_api_key }}&callback=initMap" async defer></script>
Personalization capabilities are built into templates by the developer. There are a couple key objects that allow you to set and get visitor data. These are client, session, and user. The example below is a template snippet used for a thank you page after a demo request form is submitted. It sets a new sesson variable demo_requested to true.
{% set_session demo_requested:true %}
<h1>Thank You!</h1>
Your form submission has been received and an account rep will be in touch soon!
On our next load of a page, we can check whether or not the visitor has requested a demo and if so, show them the next step in the conversion funnel.
{% if session["form01_downloaded"] == true %} <h2>Can't wait to chat!</h2> <div>In the meantime, here's a <a href="#">cool whitepaper</a> you can read about another success story.</div> {% else %} <h2>Signup for a Demo</h2> <div>Fill out the form below to signup for a demo</div> <form>.....</form> {% endif %}
This is just a small glimpse into personalization but hopefully you see the power a few lines of Liquid code can have. In Marketpath's site, we ask the visitor if they're a marketer, developer, agency, or general visitor type. From there, we allow editors to select what persona content is meant for and only display that content if a specific persona is selected and matches the visitor's selected persona.
The sky is the limit with what you can do with Liquid and we continue to expand on it.
Why not give it a try? Register and create a site now. It's completely free to use while learning and playing around in preview mode.