Support :: Skinning Sites

CMS Scripting & Tokens, TWIG and Skinning a Theme/Template

CMS Scripting and Tokens

Tokens

reference for your tokensTokens are snippets of text that enable you to output content dynamically on your website. They are a powerful tool to help you save a lot of time and money. For example, you can use tokens to automatically output the latest blog posts on your homepage, a mass email signup form, login/logout links, and much more.

To access the tokens available for your use, simply click on the orange gear icon at the top right of the admin interface (just to the left of the "Hello User" link). A comprehensive list of tokens available for your use will now display in a new tab.

Again, tokens are used to output content dynamically from one of the installed software modules. Here are some ways tokens can be used:

  • outputting a list of subpages on a web page
  • outputting the contents of a component
  • displaying a list of featured or recent listings, shopping cart products, blog posts, and more.
  • output the current temperature or weather forecast

You can use these tokens any where in Pages. Just copy and paste them. It's preferred to paste directly into the html.

Since tokens are dynamic variables built for platform use. They can be used in the html of web pages, in components and in skin segments (where twig is not turned on). The current "global" tokens and their definitions are listed below. There is also a token library reference for each module -  indicated by the orange gear icon at the header of the backend next to the help icon. Newer themes are using TWIG tokens as indicated.

If you would like to use a token in the skin editor - you will need to determine if TWIG is turned on or not. If it's turned on - you will  need to convert your tokens to TWIG using the reference below.

{{ token('insert_nontwig_token_here') }}

Use this token to output nontwig versions of tokens. This will generally be used in the header and footer. For example - if you want to output the sub pages of an existing page you would use the token #cms(subs)#. If your site has TWIG turned on - you would use: {{ token('#cms(subs)#') }}

Examples of real tokens:

#cms{subs}# becomes - {{ token('') }}

#cms{siteroot}# becomes - {{ token('https://www.lunasoft.com/') }}

Using a Token

Suppose you have a Lunasoft Shopping Cart and would like to automatically display featured products on your homepage. You could start writing content and adding pictures, but that would take more time than necessary and require frequent updating. After clicking on the gear icon, you will then see this page with the available tokens for your shopping cart:

token-index.png

Of course, there are much more, this is just an example of a few of the tokens that can be used in connection with the shopping cart. Parameters are the values you will be putting in the token to customize it to suit your needs. In the case of the "featured products" token, the parameters are the number to output, the size of the image to output, the amount of description text to output, etc. Go ahead and click on those parameters to see a popup with more information on how to use them.

After completing a token, you will want to place it into the page editor where you would like to output the content. In this example, we want to place the token just under our "Best Selling Flies" section of our page.

token-usage.png

After saving these changes, you will now see that the token is outputting the products in the desired area.

    1. #cms{siteroot}# - relative path to home
    2. #cms{skin_stylesheet}# - relative path to primary stylesheet
    3. #cms{global_stylesheet}# - relative path to global stylesheet
    4. #cms{skinfolder}# - relative path to site skin files
    5. #cms{meta_title}# - outputs the meta titles stored by the user on a specific web page
    6. #cms{meta_keywords}# - outputs the meta keywords stored by the user on a specific web page
    7. #cms{meta_description}# - outputs the meta description stored by the user on a specific web page
    8. #cms{addjavascript jquery}# - outputs the current jquery path
    9. #cms{addspecial lightbox}# - outputs the current lightbox library path
    10. #cms{addspecial jquery.video_pop}# - outputs the current jquery video_pop library path
    11. #cms{addspecial jquery.ui}#>
    12. #cms{addspecial jquery.video_responsive_pop}#
    13. #cms{addspecial highlightjs}# - outputs the current highlights js library path
    14. #cms{addspecial fontawesome}# - outputs the current font awesome library path
    15. #cms_if logged_in# something here #cms_if_end# - dynamic operator based on if a user is logged in. Put your dynamic content between the tokens if and if_end.
    16. #cms_if not_logged_in# something here #cms_if_end# - dynamic operator based on if a user is not logged in
    17. #cms{selected_class_out index}#
    18. Below you will see old syntax for adding dynamic pieces to skin segments. We didn't want the token parser looking at these (the reason they are not tokens). These are old skin segment tokens but are backwards compatible.
      1. @cms{start_footer_navigation}@
      2. @cms{dynamic_body_bottom}@
      3. @cms{navigation_page_name}@
      4. #cms{component Headers Logo}# - outputs the component with the name "Headers Logo" defined by the user in the components area.
      5. @cms{region main}@, @cms{region region_1}@, @cms{region region_2}@ - and so on output the region content saved if the site is configured for regions.

Using If Statements To Output Links Dynamically

The Lunasoft platform enables you to detect if a user is logged in or out, and display specific content for both of those scenarios using "if then" statements. You can use the tokens in the picture below for this purpose:

user-token.png

Examples:

#cms_if logged_in#

<a class="login_logout login_logout_logout" href="https://www.lunasoft.com/account.php">My Account</a>
<a class="login_logout login_logout_logout" href="https://www.lunasoft.com/login.php?logout">Logout</a>
#cms_if_end#
#cms_if not_logged_in#
<a class="login_logout login_logout_logout" href="https://www.lunasoft.com/login.php">Login</a>
#cms_if_end#

Examples:



<a class="login_logout login_logout_logout" href="https://www.lunasoft.com/login.php">Login</a>

 

Some common paths and tokens (both TWIG and non-twig) are shown below.

{{ site_root() }}

site absolute path. In live mode - www.yourdomain.com, in staging mode - yourdomain.lunasoft.com/yourdomain.com

{{ site_root_proto() }}

site absolute path with the protocol. Same as above but prefixed with http:// or https://

{{ skin_web_path() }}

Used to reference the skin files from within the skin header, footer, home, layouts, subapages, etc.

# cms{skinfolder} #

Used to reference the skin files from within the skin CSS. Note: remove the spaces from the token above in order to use it.

{{ n.dynamic_header|raw }}

Used for outputting dynamic dropdowns in the header navigation.

{{ cms_twig.component_body_html('component name')|raw }}

Used for outputting the components in the header/footer.

/uploads/site/site_number/skin/

Used for outputting the path to the skin files in widgets. Note: replace "site_number" with the number specific to your website.

{{ cms_twig.add_javascript('jquery') }}

Output the platform's latest version of Jquery onto the site. Typically used in the header.

{{ cms_twig.add_special('lightbox') }}

Output the javascript file that allows for images to take on lightbox animations.

{% if cms_twig.is_page_url('page_url_here') %} {% endif %}

Logic that outputs content/code only when on the defined page. (For example, if we are on the homepage, run home.js)

{% if not cms_twig.is_region_blank('index') %} {% endif %}

Logic that outputs the content only if the region is not empty.

{% if cms_twig.is_page_url('index') != true %}{% endif %}

Logic that outputs content/code only on the subpages.

{% if cms_twig.is_live() %}{% endif %}

Logic that outputs content only if the site is live (not on the staging site).

{% if cms_twig.is_component_active('component_name') %}{% endif %}

Logic that outputs content only if the defined component is set to active.

# cms{skin_variable variable_name} #

Used in the stylesheet to define colors to be used in connection with the styler. Note: remove the spaces from the token above in order to use it.

# cms{subs nav name-of-page} #

Used to output a page's subpages in a dynamic dropdown. Note: remove the spaces from the token above in order to use it.

 

Employee Training

skin-editor.jpgSkin Editor

You can put any website layout, template or theme onto the LunaSoft platform. When you configure a theme to work on the platform we call this "skinning" the them as you're adding that "skin" or look and feel to the platform. Once a theme has been added, it can be made available for others to use via an export feature. In addition approved themes can be added to the base themes for credit or resale.

Approved partners have access to the skin editor. Customers on advanced plans and above can request skin editor access. Whether you want to "skin" a site to the platform or just edit an existing theme you will need this access. This requires html/css and JavaScript knowledge. In some areas we use TWIG sytax for dynamic code expressions.

Go into the admin of the website, then go to Pages -> Settings -> Skin Editor. For any references to location in the following steps, they will all originate from this area.

There are several areas of the skin editor:

  1. Skin Segments
    1. stylesheet - where primary stylesheet code is located.
    2. admin_stylesheet - affects styles on the page builder backend. Useful if you want your code within widgets to look more like the front end. For an internal example see SanFranTest or dogsmeowtest
    3. header - where the header code of the site resides
    4. footer - where the footer code of the site resides
    5. home - code relevant to just the home page.  Useful if you want to use the regions feature or a layout specific to the home page. If home widgets are turned on - this is less useful.
    6. sub_page - the default layout for sub pages of the site
  2. Skin Files
    1. View Files
    2. Upload Files
      1. Note: Site Skin Files Path - /uploads/site/1/skin/yourfilename.jpg
  3. Page Layouts
    1. Custom Layouts - can be created by adding them. These are then accessed from the page builder advanced tab, layout drop down.
  4. Options
    1. Default Skin - once you have customized a skin - you can set it as the "default". This takes a snapshot of the skin code in time allowing you to revert back to that code later should you want to.
    2. styler.jpgStyler - allows you to style the site from a color picker if the "advanced Conf" has been configured with style variables or palettes.
    3. Advanced Conf - (see legend/help icon for more info in advanced conf area) allows you to write json code to create a "styler" panel that allows novice users to select color palettes, color variables or font styles that dynamically update the style sheet without the user having to know css or html. This is useful if you want to use a popular template a lot and quickly change common colors in the template/theme.
      1. Table style
      2. general styles
      3. link styles
      4. (see jeepsfreekdating for sample)
      5. we also need to show an actual css example in the legend
    4. Import/Export - allows you to export the current theme into a zip file prepared for the LunaSoft platform. This export can also be imported back into the platform for a website instance.
    5. Choose Skin - gives access to pre-skinned themes to use as a starting point for a website instance. At the time of this writing we have Standard (basic themes - non responsive) and Advanced themes - (responsive with animations) that are already skinned. Some of these themes do not have the styler/advanced config prepared or were created before the widget panel - so they may have regions which are slowly being deprecated.
  5. Software Layouts - these are the current layouts of the software modules that can be overridden.  Once a layout has an override - it is detected by the icon change in that area or you can view all customized layouts by clicking on "all customized" at the bottom. Variables that were removed and new variables may not be readily accessible without knowledge of the change - so it is wise to keep a history. Of course you can always attempt to override a software global style layout with css changes to the primary stylesheet when no html changes are needed.

Code requirements to skin

Semantic Code - The code should be semantic, meaning that if there needs to be a heading display it should not use <span class="heading"> it should use a <h2> or <h1> ( likewise if something is a list, it should be a <ul> or <ol> and not a set of <div> ). This is important primarily for the areas that the client will be able to edit. The client edits their pages using the wysiwyg editor ( tinymce ). The client is not html savvy, however they are trained how to use the tinymce features for lists, headings, paragraphs, etc. The client must not be forced into html mode to edit their content. If we used <span class="heading">, the client would not be able to reproduce that style without going into html mode.

Existing Libraries

Jquery/js framework usage - Because the platform already uses Jquery, you can load the path dynamically by using a TWIG call OR a token call.  If you need a different version of Jquery - you will need to load the jquery library for the pages that need it. The platform uses jquery for many software functions and will include it automatically when needed/not included already. So if you were to load your own version of jquery, it would directly conflict with what the platform loads ( see FAQ below for information on how to load jquery correctly when you skin ).

FontAwesome - is also a library already on the platform. See below how to add.

<link href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css' rel='stylesheet' type='text/css'>
<script>
      $(document).ready(function() {
                $('.fa').each(function(){
                    var c = $(this).text();
                    $(this).html('');
                    $(this).addClass('fa-'+ c);
                });
            });
      </script>

TWIG

TWIG - the platform allows for TWIG in the skin editor. Twig will not work on the web builder. You can use TWIG in: stylesheet, admin_stylesheet, header, footer, home, sub_page, custom page layouts, and modules "Software Layouts". The current "global" TWIG tokens and their definitions are listed below. All twig functions live on individual objects. (i.e. class file underneath cms module)

  1. {{ content.main|raw }} - outputs content from database of main region 
  2. {{ content.region_2|raw }} - outputs content from database of region 2, (regions no longer used on most new themes - but up to 6 regions available)
  3. {{ skin_stylesheet }} - outputs primary stylesheet in skin/segments
  4. {{ global_stylesheet }} - outputs global stylesheet from system (styles software modules)
  5. {{ cms_twig.component_body_html('header logo')|raw }} - outputs the component with the name "header logo" defined by the user in the components area.
  6. {{ skin_web_path() }} - outputs relative path to site root
  7. {{ cms_twig.dynamic_header()|raw }} - loads code in dynamic header
  8. {{ cms_twig.dynamic_body_top()|raw }} - loads code in dynamic body. I.e. needed or saved parts for opening body tag such as google analytics(analytics area), dynamic content (pages/settings), live chat, social media (configuration).
  9. {{ cms_twig.add_javascript('jquery') }} - outputs jquery from system
  10. {{ cms_twig.add_javascript('js/jquery.cookie.js') }}
  11. {% if cms_twig.is_page_url('index') %}   {% endif %} - dynamic logic to output content based on a page url name
  12. {% if cms_twig.is_component_active('header login') %} {% endif %} - if a component is active then output content
  13. {% if cms_twig.is_live() %}  {% endif %} - will dynamically output content based on whether site is set to active or not. Handy if you don't want html showing until site is live and approved by client.
  14. {% if cms_twig.is_user_logged_in() %}  {% else %}  {% endif %}
  15. {{ cms_twig.user_first_name() }} - will output logged in user first name
  16. {% if cms_twig.is_user_loggedin_in_group('rabbit') %} you are in the rabbit group {% endif %} - detects if logged in user is in a user group
  17. {% if cms_twig.is_user_logged_in() %} I am logged in {% else %} I'm not logged in {% endif %} - checks if a user is logged in

Code Samples using Twig

{% if cms_twig.is_page_url('index') %}   {% endif %}


{% for n in navigation_links %}
<li>
<a {% if n.selected %}class="selected"{% endif %} href="{{ n.link_url }}" {% if n.link_title %}title="{{ n.link_title }}"{% endif %} {% if n.is_target_blank %}target="_blank"{% endif %}>{{ n.name }}</a>
</li>
{% endfor %}


@cms{start_primary_navigation}@
<li class="@cms{navigation_if_selected_class active}@ @cms{dynamic_dropdown_active_class}@">
<a href="@cms{navigation_url}@" @cms{navigation_link_title}@ @cms{navigation_external_url_target_blank}@>@cms{navigation_page_name}@</a>
<div class="dynamic_dropdown">@cms{dynamic_dropdown}@</div>
</li>
@cms{end_primary_navigation}@


{% if cms_twig.is_live() %}
<div class="luna">
    <p><a href="http://www.lunastudios.com" title="Professional Web Design">Design By Luna</a></p>
</div>
{% endif %}
The code above will ouput html content when the site is set to "live" in site "edit" area accessible to super admins. In this case when the site goes live we are ouputting a link to LunaStudios.


{% if cms_twig.is_component_active('header login') %}
    <div class="header-login">
        <div class="container-fluid">
          {{ cms_twig.component_body_html('header login')|raw }}
        </div>
     </div>
{% endif %}

The code below shows how to use else statements using twig.
{% if cms_twig.is_user_loggedin_in_group('Study Club') %}
<a href="//www.pccdental.com/my-membership.php">My Study Club Membership</a>
{% else %}
<a href="//www.pccdental.com/international-study-club-info.php">Christensen International Study Club</a> {% endif %}

Advanced Config - JSON Styler

  1. json - styler -
  2. body {
      font: 400 15px/22px "Lato", sans-serif;
        color: ;
      background: #f2f2f2;
    }

    a {
      text-decoration: none;
      transition: all 0.3s ease;
        color: ;
    }
    a:hover {
      color: ;    
    }
  3. h3 {
      font: 400 27px/28px "Lato", sans-serif;
      color: ;
      text-transform: uppercase;
    }
    .btn-default {
      display: inline-block;
      background: ;
      color: #ffffff;
      text-transform: uppercase;
      font: 700 16px/16px "Lato", sans-serif;
      padding: 9px 27px 11px;
    }
    .btn-default:hover {
      background: #32a41f;
      color: #ffffff;
    }
    .btn-big {
      display: inline-block;
      background: ;
      font: 400 24px/33px "Lato", sans-serif;
      color: #ffffff;
      text-transform: uppercase;
      text-align: center;
      padding: 18px 40px 20px;
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
        border: 0;
    }

CSS Resets  - It is recommended that you do not use css resets with your code. If you must use a reset, load it before the global stylesheet is loaded in your skin. You will also need to make sure that you have added styles for the common elements that the user will create from the editor ( tags like ul, ol, li, h1, h2, h3, h4, p, strong, a, td, th, table, etc ). For example, if you reset the padding of all paragraphs to zero, and the client then puts in two paragraphs right next to each other in the editor, they will snug up against each other ( which would not look correct ). Or if you force all table cells to zero padding, areas that use tables ( such as the shopping cart checkout ) will not look correct. If you have to use a reset, be very mindful of what you are doing and the potential ramifications.

General Information

Skins are compartmentalized into skin segments ( header, footer, home, sub, and primary stylesheet ). Any additional files ( js, fonts, images, etc ) are uploaded to skin files in a flat folder ( no sub directories, for platform management purposes ).

Note: calling files from another file (like @import for additional style sheets within an existing stylesheet) requires proper syntax. Call those files directly from the "root" file path or they will not work properly.

Steps to skinning a site

  1. Upload images, js files ( but not jquery ), and any other relevant files to Skin Files -> Upload Files. There are no sub directories for skin files ( for platform management purposes ), so all files are uploaded to one place.
  2. Copy the code from your stylesheet into the stylesheet skin segment. Change all paths that should reference a file under the uploaded skin files to #cms{skinfoIder}#filename , for example if you have a css rule with a background url('some/path/image.jpg'), change it to url('#cms{skinfoIder}#image.jpg')
  3. Put the header code into the header skin segment. Look at the current contents of the default header skin segment and configure your header in the same way. There are tokens there to output page title, description and keywords. There are also tokens for including the global stylesheet for the platform and the stylesheet skin segment. There are a couple other tokens that must be placed at the end of the head area and at the beginning of the body area ( please observe those from the default header skin segment ). The main navigation uses tokens to signify the individual menu items and tokens within those to output the links. If you need to include any assets from the uploaded files ( images, stylesheets, javascript ) remember to use #cms{skinfoIder}# for the path.
  4. Add the footer html to the footer skin segment. The footer skin segment works very similarly to the header skin segment, observe the similar tokens and use them in your footer similar to how they are used in the header.
  5. Add the homepage html ( not header or footer ) to the home skin segment. Please note that there are tokens here to output the different regions from the content management system. Obeserve how they are laid out in the default home, and use them to replace content areas where users can edit. Take the content that the token replaces and insert it into the corresponding homepage region ( under Pages, edit the homepage and put in the html to the appropriate region )
  6. Add the sub page html ( without header or footer ) to the sub_page skin segment. Follow the same rules and procedures as the home skin segment concerning tokens. Take note that on sub pages, region_1 will automatically include the sub page navigation. If you do not want the sub page navigation, use a different region.
  7. Any elements on the site that should be user editable, but are not suitable for a region need to be created as a component ( under Pages -> Components ). These are used for global elements such as copyright in the footer, logo in the header, or an additional navigation for the header. To include a component in any skin segment use ( without square brackets of course )
  8. Set region names ( under Pages -> Settings -> Region Names ). Enable or disable regions as they are used or unused, name them something that a client would recognize. For example, if you put a region on the homepage near the top, an appropriate name might simply be "Top". Or if you have 3 columns on the homepage ( separated into 1 region per column ), appropriate names might be Column 1, Column 2, etc

Tips

  • Put your logo as a true image in the code ( not a background image ), wrap it in a div and style the div's position. Logos should always be client editable, so place the logo itself into a component. No class should be on the image itself, which is why we put the class on the wrapping div
  • for example:
    <div class="logo"><a href="#cms{siteroot}#"><img src="logo.png" alt="" /></a></div>

    Option A. #cms{component headers logo}# (token for component in page builder)

    Option B. {{ cms_twig.component_body_html('header logo')|raw }} (token for component in skin area)

    <a href="https://www.lunasoft.com/"><img src="logo.png" alt="" /></a>
    
     - would then be stored in a component in pages/components and you would replace this html with the proper component shown above like this:

    Option A. <div class="logo"> {{ cms_twig.component_body_html('header logo')|raw }}</div> (if code is stored in the skin (header, footer, home/sub_page, etc.)
    
    Option B.  <div class="logo">
    #cms{component headers logo}#</div>  (if code is stored in a web page)
    
  • Do not use sprites for things that clients should be editing
  • Our footer link should go in the skin instead of a component, as it makes it less likely that admins will take it out.
  • All animation files (SWF's) / assets must be uploaded into the Files module and referenced from there.

FAQ

How do I add jquery to the header for the site?

In the header skin segment, before the @cms{dynamic_header}@ put a token #cms{addjavascript jquery}#. If you use additional javascripts that depend on jquery, make sure to include your javascripts after the @cms{dynamic_header}@. The token to include jquery will place the jquery inclusion inside the value for @cms{dynamic_header}@, so any scripts in your skin that depend on it should be loaded after. If you uploaded the javascript to the skin upload files, after @cms{dynamic_header}@, put <script src="#cms{skinfolder}#nameofscript.js"></script>

Sample Skinned Site and Customization

The site below was skinned and a customization of the theme is also shown.

See code for this theme http://mhub.lunasoft.com/uploads/skins/54320/demo/
and the theme customized on the platform here: http://smofa.lunasoft.com/smofa.org/
Below is shown the code used in each section of the theme segments as well as custom layouts created for wide and wide full.

home


<div class="wide_fluid_container">{{ content.main|raw }}</div>

sub


<div class="container">
<div class="row row-md-reverse row-sm-reverse">
<div class="col-sm-9">{{ content.main|raw }}</div>
<div class="col-sm-3 sub_left_col">{{ content.region_1|raw }}</div>
</div>
</div>

wide


<div class="container">
<div class="row">
<div class="col-sm-12">{{ content.main|raw }}</div>
</div>
</div>

wide full


<div class="wide_fluid_container">
<div class="row">
<div class="col-sm-12">{{ content.main|raw }}</div>
</div>
</div>