Data Types 

Elements can be defined as many types of data. 

The type determines what UI will be generated for each input.

to store an element we must give 2 attributes to a html element, a data-slug and data-type, we can also add additional data tags to add different functionality.

Data slugs must be all lowercase, contain no dashes use underscores. It should describe a bit of the function of the element is, in some cases the user will see the slug. Keep in mind that for each page all slugs must be unique. 

A good slug would look like this,



The text is the most versatile data type and will be used quite often. It allows users to enter text with the ability to change the styles. They also have the header options defined by you in the back-end.

A common use case for text.

<div     data-slug="my_text_element"     data-type="text">    {{ my_text_element.text | safe }}</div>

Note the use of safe text.

We also wrap the text in a div, since the text will generate it's own HTML elements we must wrap text with a div.

Plain Text

Only edit the text with no style control we use plain text. When plain text saves it strips all html out of the text field. 

Common use cases are for headers, buttons with static links.

<h2     data-slug="my_plain_text_field"    data-type="plain_text">    {{my_plain_text_field.plain_text}}</h2>


Create link able content.

This element contains 2 fields the user can fill out, url_text and url_link.

These are both plain text fields. 

The user should be educated on how to use tel: and mailto: text, we should probably just add these as features...

Text elements can have links embedded in them, make sure that using a text element is not a better solution.

<a   href="{{my_first_link.link_url}}"   data-slug="my_first_link"   data-type="link">   {% if not my_first_link.link_text %}     link text...   {% endif %}   {{my_first_link.link_text}}</a>

The conditional statement of if not text is optional this makes editing the text easier.


Images are use in 2 ways mostly, background and as a img tag, we also associate a lot of meta data with the images.

Basic use case as Image as an img tag

<img  src="{{first_image.image_url}}"  data-slug="first_image"  data-type="image"  alt="{{first_image.image_alt}}"  >

There are other optional fields  on images;

first_image.image_alt first_image.image_link first_image.image_reference

These should be used as need be, image_reference is good for photo credits and the link then can be used for linking to the credited artist. 

Using images as background images, we create an element for the admin to use to select the image. We then we assign the image to the element we want to have the background image.

{% if request.user.is_superuser %}  <div    data-slug="my_image"    data-type="image"    data-container="{{}}"  ></div>{% endif %}<div  style="background-image: url({{my_image.image_url}});"></div> 

You should only be applying the background image with your in-line styles.

For other sizes of the images append _s _m _l to the image_url. The size of these images are determined in your settings file.

small image {{my_image.image_url_s}}medium image{{my_image.image_url_m}}large image {{my_image.image_url_l}}

To test if an image exists use

{% if my_image.image.uploaded_file %}{% endif %}


This would be for example a pdf or a zip. Something you want some one to download.

<a  id="reload_{{}}"
  href="{{data.my_file.file_url}}"  data-slug="my_file"  data-type="file">  Download {{data.my_file.file_name}}.</a> 

The Admin will see a edit button in order to edit/select the file similar to the image tag.


For embedded linked videos from Youtube or Vimeo.

<a  class="values_video"  href="{{values_video.video_link}}"  target="_blank"  data-embeded='{{values_video.get_video_embed|safe}}'>  <img    src="{{values_video.video_image}}"    alt="{{values_video.image_alt}}"    data-slug="values_video"    data-type="video"></a>

For videos reference Video


This tag saves us from making multiple templates, it's a lazy way to give diversity to a site. When using the type call the variable in tin-line css. When using colour avoid setting the colour in css this will cause issues with our inline css cascading.

<div data-slug="my_first_colour" data-type="colour"></div>

The dev will only render in admin mode as a colour picker. When placing this div in the HTML take into consideration the impact on the flow of editing the site.


Booleans are really useful for making the page's data more dynamic.

You would usually add this inside of an admin view area only, it appends before the element a checkbox.

{% if admin %}  <p>   <span     data-type="boolean"     data-slug="boolean_example"     data-container="{{}}"   ></span>   toggle the input  </p>{% endif %}

{% if data.boolean_example.boolean %}  <h1>This will be toggled based on the input</h1> {% endif %}

<div class="pure-u-1 {% if data.boolean_example.boolean %}mobile_hide{% endif %}">  <p>   If the boolean is check this will have an added class of mobile_hide...  </p></div>

We have two example use cases, where we hide a whole section when the boolean is selected and an other where the boolean adds a class to the element.


Constants are great for nav/footer elements logos, anything that will be used on multiple pages and won't be different.

Add the constant attribute to any element you want accessible on all pages. This modifies the element and can be applied to any element.

  <h2   data-slug="website_name"   data-type="plain_text"   data-constant="true"  >   {{constants.website_name.plain_text}}  </h2> 

When adding the constant attribute be sure to also modify your variables to access the constant content. In this example notice we placed constants in-front of website_name.


In order to have a variable number of sections on a page we create a container to repeat the same content. This allows users to have greater control over the amount of content there is on the page.

Containers modifier the other tags and requires a few elements of it's own.

<div data-slug="demo_container" data-type="container"> {% for container in demo_container.containers %}{% with as data %}    <h1      data-slug="first_para"       data-type="plain_text"       data-container="{{}}"    >       {{data.first_para.plain_text}}     </h1>      {% if request.user.is_superuser %}        Do some admin stuff only in here...       {% endif %}     {% include "page_cms/container_ui.html" %} {% endwith %}{% endfor %}</div>

There is quite a bit going on here, breaking it down we create an element called demo_container, which contains pages that act as containers. Each of these containers has it's own instance of first_para. Since there is now multiple instances of first para on a single page we need to reference first_para with a data in-front of it. That is the technical way of looking at it, an easier way of looking at it is we've created a namespace tool that allows us to have multiple instances of the same value.

We also include container_ui.html to add functionality to the containers/loops we've just made.

You should also wrap the container content with a div for each element 

<div id="pc_page_{{}}">    your looped content in here...</div>

This ID will allow for easier page reloads

An other optional feature for this section is 

{% include "page_cms/container_ui_advance.html" %}

This advance UI is used for organizing long lists, we may add other features there.

If each element in the list 

{% for container in first_container.containers %}{% with as data %}  <div id="pc_page_{{}}">   {% include container.get_component %}   {% include "page_cms/container_ui_component.html" %}   {% include "page_cms/container_ui.html" %}  </div>{% endwith %}{% endfor %}

The include get_component element should be written with the proper tags


Otherwise the variables inside of each component will compete with each other.