Base CMS Made Simple page template with automated metatags
Previous article Next articleHow to build a CMS Made Simple™ page template and show the news/blog title as the page title, get the correct canonical value for module detail pages, pass a correct image to social media websites, etc... I will describe here how to do that with just clever use of Smarty in your templates.
Important is to first understand the way templates are processed in CMSMS™.
The Core::Page template contains three different areas:
<head> <!-- Area 2 --> </head>
<!-- Area 3 -->
The areas are rendered in the order: one, three and two!
To pass data between these areas this order is important. To use a parameter it has to be processed in the same area or in an area before it.
The advantage of processing parameters in the top of the page template (area 1) is you can use the parameters globally.
The module output will be processed at first, after that the content blocks. When that is done and variables don't have a value the default values are entered. No need for if this than that or else... logic in the top or the content of a template.
Because I re-use the values in other template areas/scopes I added scope=global to the assigned parameters.
Read here much more about Smarty scope »
How to use
The base Core::Page template
The content of the template in Design Manager:
{strip}
{process_pagedata}
{$theme_url = "{root_url}/assets/themes/name" scope=global}
{$content = "{content}" scope=global}
{$canonical_url = $canonical_url|default:"{$content_obj->GetURL()|lower|default:''}" scope=global}
{*RedirectCanonical canonical_url=$canonical_url exclude=''*} {* -> http://cms.ms/9xmT *}
{$root_url = $root_url|default:"{root_url}" scope=global}
{$short_url = $short_url|default:$canonical_url scope=global}
{$previous_url = $previous_url|default:"{cms_selflink dir='prev' urlonly=1}" scope=global}
{$next_url = $next_url|default:"{cms_selflink dir='next' urlonly=1}" scope=global}
{$site_name = $site_name|default:"{sitename}" scope=global}
{$page_breadcrumbs = $page_breadcrumbs|default:"{nav_breadcrumbs}" scope=global}
{$page_description = $page_description|default:"{description}"}
{$page_description = $page_description|default:$content|strip_tags:false|strip|trim|truncate:300|default:'' scope=global}
{$page_image = $page_image|default:"{$theme_url}/page_image.png" scope=global}
{$page_lang = $page_lang|default:'en' scope=global}
{$page_modified = $page_modified|default:"{modified_date format='%e-%m-%Y'}" scope=global}
{$page_title = $page_title|default:"{title}" scope=global}
<!DOCTYPE HTML>
<html lang="{$page_lang}">
{* ++++++++++++++++++++++++ Area 2 ++++++++++++++++++++++++ *}
{/strip}<head>{strip}
<title>{$page_title} - {$site_name}</title>
<meta charset="utf-8">
{metadata|strip}
{cms_stylesheet|strip}
{/strip}</head>{strip}
{* ++++++++++++++++++++++++ Area 3 ++++++++++++++++++++++++ *}
<body>
<header>
<h1><a href="{$root_url}">{$site_name}</a></h1>
</header>
<nav>
{Navigator|strip}
</nav>
<main>
{$page_breadcrumbs}
<h2>{$page_title}</h2>
{$content|strip}
</main>
<footer>
<p>This page is last modified: {$page_modified}.</p>
</footer>
</body>
</html>
{/strip}
Available global parameters in the template
To output the regular content block in the main content area
The canonical url for a regular page and if set in a module overwritten to the detail url for the module detail page.
The root url of the website. Can be useful in multi domain websites.
The shortened url of a regular page or if set in a module overwritten to the shortened detail url for the module detail page.
This tag is set so it can be used at multiple spots in your templates. If you move the website or template you only need to change the path once.
In this example all theme files are stored in www.website.com/assets/themes/name/.
The website name
Create your custom breadcrumb trail for modules. How? Read this tutorial ».
The description of the page. First looks at the description field in the content page, second if a module has the description set and third a summarize of the content tag.
The full path to the image that is used when the website url is linked from social media websites and apps.
The default website image is named page_image.png and is stored in www.website.com/assets/themes/name/ = {$theme_url}.
If you have a separate image set in your news/blog module this one will be used instead.
Don't make the image to small otherwise it will be ignored by Facebook. I don't know what the "official" requirements are, but in my experience it must be at least 500px.
Set the language once. Is useful for multilingual websites.
When is the page or module detail information last modified.
The page title, first the title set in the page editor and if set in the module detail template the title of the i.e. news article.
Pass data from modules to the page template
Two examples how to use module data in the Core::Page template.
News module
Move this code to the top of your News module detail template:
{$page_description = $entry->summary|default:$entry->content|strip_tags:false|strip|truncate:300 scope=global}
{$page_modified = $entry->modified_date|date_format:'%e-%m-%Y' scope=global}
{$page_title = $entry->title|cms_escape:htmlall scope=global}
Optional: First create field definition Image: "photo".
{$page_image = "{uploads_url}/news/id{$entry->id}/{$entry->fields.photo->value}" scope=global}
{/if}
CGBlog module
Move this code to the top of your CGBlog module detail template:
{$page_description = $entry->summary|default:$entry->content|strip_tags:false|strip|truncate:300 scope=global}
{$page_modified = $entry->modified_date|date_format:'%e-%m-%Y' scope=global}
{$page_title = $entry->title|cms_escape:htmlall scope=global}
Optional: First create field definition Image: "photo".
{$page_image = "{$entry->file_location}/{$entry->fields.photo->value}" scope=global}
{/if}
You can do similar for other modules that have detail pages, like Company Directory, Products and Uploads module. Don't forget to change the Smarty strings according the module's requirements.
Automate your metadata tags for SEO purposes
Now we have all parameters globally available, we can use them for setting the metadata tags. A few examples:
General tags for the <head></head> area
<meta name="copyright" content="Copyright (C) Your name, All Rights Reserved"> {* <- Change this *}
<meta name="description" content="{$page_description}">
<meta name="generator" content="CMS Made Simple - Copyright (C) 2004-{$smarty.now|date_format:'%Y'} CMSMS™. All rights reserved.">
<link rel="canonical" href="{$canonical_url}">
<link rel="shortlink" href="{$short_url}">
<link rel="start" href="{root_url}">
{if !empty($previous_url)}<link rel="prev" href="{$previous_url}">{/if}
{if !empty($next_url)}<link rel="next" href="{$next_url}">{/if}
Open Graph tags for Facebook in the <head></head> area
<meta property="og:image" content="{$page_image}">
<meta property="og:site_name" content="{$site_name}">
<meta property="og:title" content="{$page_title}">
<meta property="og:type" content="website">
<meta property="og:updated_time" content="{$page_modified}">
<meta property="og:url" content="{$short_url}">
Meta tags for Twitter in the <head></head> area
<meta name="twitter:creator" content="@yourtwitter"> {* <- Change this *}
<meta name="twitter:description" content="{$page_description}">
<meta name="twitter:dnt" content="on"> {* do not track visitors *}
<meta name="twitter:domain" content="{$root_url}">
<meta name="twitter:image" content="{$page_image}">
<meta name="twitter:site" content="@yourtwitter"> {* <- Change this *}
<meta name="twitter:title" content="{$page_title}">
<meta name="twitter:url" content="{$short_url}">
Because the {metadata} tag is in the head area of the page template, you can also add the meta code above in the Global Metadata field in the Global Settings Admin page!
Test and Debug Lines
Put these lines in the body area of your CMSMS Core::Page template and you can use them to test and debug your work!
<hr />
<p><b>+++ TEST AND DEBUG LINES +++</b></p>
<p><b>$site_name:</b> {$site_name}</p>
<br />
<p><b>$canonical_url:</b> {$canonical_url}</p>
<p><b>$root_url:</b> {$root_url}</p>
<p><b>$short_url:</b> {$short_url}</p>
<p><b>$theme_url:</b> {$theme_url}</p>
<p><b>$previous_url:</b> {$previous_url}</p>
<p><b>$next_url:</b> {$next_url}</p>
<br />
<p><b>$page_breadcrumbs:</b> {$page_breadcrumbs}</p>
<p><b>$page_description:</b> {$page_description}</p>
<p><b>$page_image:</b> {$page_image}</p>
<p><b>$page_lang:</b> {$page_lang}</p>
<p><b>$page_modified:</b> {$page_modified}</p>
<p><b>$page_title:</b> {$page_title}</p>
<hr />
{* ++++++++++++++++++++++++++++++++++++ *}
When you are ready, just delete them.
Working example
I use this at:
Comment Form
ReviewManager
ReviewManager
12 Comments
World's First AI Video News Maker let You Create AI News Video with Amazing News Channels, Video News Website in a Click.
In ANY Niche & Language, In Less Than 60 Seconds!
For more click here : https://warriorplus.com/o2/a/cqwh3hw/0
alert('XSS BUG DITEMUKAN')
Hello!
Wonderful article and cool solution!
According to your method, I solved 2 of 3 important tasks, the third problem remains, maybe you can solve it for everyone’s benefit.
Namely this:
There is a site sitename.com
There are a number of photo galleries broken down by year.
for example sitename.com/gallery/2018/GalleryName/125
Here are 2 cardinal problems:
1) ending the link to 125 - here, as the developer of the gallery wrote to me, the ID of the page from which the gallery script is called is substituted.
2) The canonical URL is incorrectly determined - it has sitename.com/foto in the body of the page
The question is how to make the correct display of the canonical URL sitename.com/gallery/2018/GalleryName/125 and not sitename.com/foto?
Thank you!
Hello!
How to make the Gallery module so that in the description of the album you could write meta tags name, description, keyword?
Thank!
Slightly modified your code.
On some occasions some white space was left on the beginning or end of a meta-description. Smarty does not have a trim function, but with a regular expression you can manage that also.
When you use Smarty tags inside the News summary or content you might use {eval} first. {eval var=$entry->summary|strip...} did not work for me so I am using a capture block first and do the stripping after.
{capture assign='_summary'}{eval var=$entry->summary}{/capture}
{capture assign='_content'}{eval var=$entry->content}{/capture}
{$_summary=$_summary|strip_tags:false|strip|truncate:300:'':false:false|regex_replace:"/^[\s]*(.*?)[\s]*$/":"$1"}
{$_content=$_content|strip_tags:false|strip|truncate:300:'':false:false|regex_replace:"/^[\s]*(.*?)[\s]*$/":"$1"}
Hi. The article you wrote is great and i tried to integrate the code "The base Core::Page template" into a test page template . Can u support the integration? If yes pls. write to my email. Thx
Can i send you the currently our used template (or give you access 2 admin) and
sorry out of topic, i am use {cms_init_editor} for microtiny or Tynmce (rolf) but all wysiwyg not work at cgblog "frontend form submit"...
only class="xxx microtiny" at texarea form (frontend), but js/css link not show at this page ???
ex:
https://lokakdipalembang.info/mylokak
{cgsmartimg action=responsive} also not work. in pagr not output link or css
can you help me ¿¿¿
@Daniee
You have read this blog about template inheritance?
https://www.cmscanbesimple.org/blog/the-power-of-template-inheritance-and-the-cmsms-design-manager
I'm using a template "master" with your automated meta tags (i.e.: {$page_title = "{title}" scope=global} and
{block name="content"}
{$content}
{/block}
In the "child template" I insert
{extends file='cms_template:Master'}
{block name=content}
myContentHere
{/block}
but if I use this child template for News or CGBlog and insert in the detail template
{$page_title = $entry->title|cms_escape:htmlall scope=global}
the page title is not filled with the post title
If I use a standard template your code is ok and the page title is filled with the post title.
What do you mean with child templates?
It seems not be working with child templates, isn't it?
Thanks, great article...