TTWeb Advanced Config 1. Region Config

Overall setup and file placement

Region Configuration is set up as Jekyll Site data - it’s a hash of key-value pairs set up with site.data._region_config. This means it can be combination of a single file at _data/_region_config.yml or individual files at _data/_region_config/_key.yml. (Technically both JSON and YML files should work, but YML is just easier to read and allows for reusable chunks within one file). So, these two setups would be equivalent:

_data/_region_config.yml:

my_region_type:
  name: "My Region Type"

_data/_region_config/my_region_type.yml

name: "My Region Type"

You can also combine them, so the following setup: _data/_region_config.yml:

my_region_type:
  name: "My Region Type"

_data/_region_config/another_type.yml

name: "Another Type"

Would result in the following site.data structure:

{
  "my_region_type": {
     "name": "My Region Type"
  },
  "another_type": {
     "name": "Another Type"
  }
}

Regions, Region items and data storage

In TTWeb sites, we have the concept of regions. If you have an editable region on the page, e.g. {% region my_region, type:html %} it creates a place for users to edit HTML content with a wysiwyg. This content is store in a JSON file at _data/_regions/[page-path]/my_region.json and would look something like

[{
  "_template": "html",
  "content":"<p>Content from the WYSIWYG editor</p>"
}]

Note that this is an array! And when you specify type:html, you’ll only ever get one item in this array. Currently, specifing type:mixed is the only way to get an editor that allows the user to create more than one Region Item. In the data we’re storing, it’s actually the region item that is associated with a _template not the region as a whole. So a “Region” can have a “type” equal to “html”, “image”, “header”, “mixed”, “my_custom_region”, etc. And a “Region Item” can have a template of “html”, “image”, “header”, “my_custom_region” - but NOT template: "mixed". The Region Type determines whether the Live-Edit UI allows for multiple items. When “mixed”, the user determines what “_template” to use for each item. For other values of Region Type, that Region Type is also set as the “_template” for the region item(s) and the user cannot control it. The Region Item’s _template value determines what specific editor buttons are available for that item (item settings, html editor, image picker, html-settings).

The configuration of a region type

A single region type can have 4 values specified

name: The name to display in the Live-Edit screen for the region type

settings: Configuration of values that can be edited on a settings screen in Live-Edit. The schema for this is exactly the same as for content model definitions. Make sure that keys for settings are kept unique from keys for editableContent. You can not have both settings.image and editableContent.image

editableContent: list of keys that specify all of the individual editable sections of a region. When a user creates an instance of a region, the data for editableContent items is stored exactly like settings items (the separation is mainly for the UI's purposes) which is why you can't use the same key names within both editableContent and settings. More on editableContent in section 5.

template: blob of HTML that acts as the template for this

OR

template_file: path within _includes/ to look for a file that contains the HTML template. Note that all of the _includes/ paths that are specified in _config.yml are used while looking for this template file.

The Template

The template content (either directly in the config or in a separate file) is just like any other jekyll include file and you can use liquid to process the data passed into it. There are some limitations due to the fact that these templates are attempted to be rendered in-browser, so difference between the standard liquid vs jekyll {% include %} tags currently cause issues - best to avoid this one and any TTWeb custom jekyll tags like {% t %} or {% region %}. For this reason, the practice is to put all of these into a subfolder named “_jekyll_includes” (which I’m now realizing is a very counter-intuitive name) to separate them from the other includes that can use the full set of jekyll tags.

The data that gets passed into the template is provided in the variable “item”. If you have the following setup:

my_region_type:
  settings:
    custom_id:
       type: string
  editableContent:
    html: ...

Then the template will be able to access data in both item.custom_id and item.editableContent

editableContent

These are a special set of “settings” keys, that correspond to editable parts of a template. This content is always either HTML or Image. (Or Header which is just an HTML editor with restrictions). You must manually set up the editing of these items in your template. Backtrack: when you write {% region my_region type:html %}, what you actually get from jekyll is something like

<div data-region='en/index.html/my_region.json' data-region-type='html''>
  <div class='tt-region_ped' data-ped-index='0' data-ped-type='html'></div>
</div>

Going to back to what was discussed in section 2, if you had {% region my_region type:mixed %} you might instead see something like

<div data-region='en/index.html/my_region.json' data-region-type='mixed''>
  <div class='tt-region_ped' data-ped-index='0' data-ped-type='html'>(etc)</div>
  <div class='tt-region_ped' data-ped-index='1' data-ped-type='my_custom_region'>(etc)</div>
</div>

When the CMS sees data-ped-type='html' it knows to turn that section into a wyswig editor when you turn on live-edit. When it sees data-ped-type=”image” it knows to turn it into an image picker. When it’s another type, it doesn’t really know what to do other than show a settings button and render the template. However, you can add your own version data-ped-type into the template to make parts of it directly editable. That’s where editableContent keys come in. Say you have a custom type that has a left-hand column with customizable content followed by a righthand column with an image on top and customizable HTML below. It might look something like (ignoring class names for layout)

<section>
   <div>Left Content</div>
   <div>
      <div><img /></div>
      <div>Right Content</div>
   </div>
</section>

In order to make all of the content editable with the correct tools, you’d specify your region types:

my_region:
  editableContent:
    left_html: [html settings *more on this later]
    right_html: [html settings *more on this later]
    top_image: [image settings *more on this later]

and add data-live-editable-type and data-live-editable-key attributes to tie it together:

<section>
   <div data-live-editable-type='html' data-live-editable-key='left_html' >Left Content</div>
   <div>
      <div data-live-editable-type='image' data-live-editable-key='top_image' ><img /></div>
      <div data-live-editable-type='html' data-live-editable-key='right_html' >Right Content</div>
   </div>
</section>

And of course you’d want to actually make the content render what the user entered, so it would actually look like:

<section>
   <div data-live-editable-type='html' data-live-editable-key='left_html' >
      
   </div>
   <div>
      <div data-live-editable-type='image' data-live-editable-key='top_image' >
         <img src="" alt='' class='h-100 objectfit'/>
      </div>
      <div data-live-editable-type='html' data-live-editable-key='right_html' >
         
       </div>
   </div>
</section>

So this tells the CMS Live-Edit tools to show an image picker over that <div> that wraps the image tag, and when a user uses it to pick an image, store that in the correct index of region items in _data/_regions/[pagepath]/region-name.json file (the indexing is done for you) in a hash that looks something like:

{
   "_template": "my_region",
   "top_image": {
        "_template": "image",
        "content": {
             "alt": "alt text entered by user with new image selection",
             "url_large": "https///url for newly picked image",
              ...lots of other image metadata
         }
    },
   "left_html": {
        "_template": "html",
        "content":"<p>Left Content</p>"
    },
   "right_html": {
        "_template": "html",
        "content":"<p>Right Content</p>"
    }
}

editableContent settings

Even more configuration options… When you specify editableContent items, they’re either HTML or Image types. Each content-item can have some additional settings (same syntax as specifying for the whole item) - so yes, you can have a region type that has a bunch of settings for the whole region-item plus additional settings for each HTML content-item within that. In Addition, there are some special keys for HTML editors used to customize the TinyMCE wysiwyg:

tinymce_style_formats: <?>
tinymce_style_formats_merge: <boolean>

These just get directly passed into the tinymce config: https://www.tiny.cloud/docs/configure/content-formatting/ Make sure you distinguish between “formats” and “style_formats” - I’m really not sure exactly how to best use these things yet. And perhaps we need to switch to another WYSIWYG that has more understandable style configuration options.

If you specify these settings, such as

my_region:
  editableContent:
     top_html:
       settings:
          custom_class:
              type: string

You can access them in the template like:

<div class=""></div>

So make sure not to name your settings keys “content”

Lastly - I believe these settings and formats currently only apply to HTML content types, not Image ones. WIP.