Creating Bespoke Modules - Eonic/ProteanCMS GitHub Wiki
Modules are features within the CMS that can be placed on blocks within pages.
Every module is organised into a folder and they can have several locations within the system.
/ptn/core/modules - These are essential modules every website must use
/ptn/modules - These are optional modules that every website has access to by default but these can be cherry picked for performance on larger projects
/modules/ - Where you can place local bespoke modules or modules you have overridden.
Module folders will contain the following files
manifest.xml - XML containing the configuration details of the module and contentTypes it uses.
form.xml - XForms for the module/content type usually named after the content type and specified in the manifest.xml
module.xsl - An xsl containing the handling of the data that is being passed through via the xForms within the same module. Usually named after the content type
style.scss - Any css required for the module
Any Images or javascript used within the module
Make sure that you have the latest version of ProteanCMS.
Create a modules folder in the root of the website and create another folder within with the name of the bespoke module that you're creating.
The fastest way to start with the creation of a bespoke module is to copy an existing module that we have already created.
So to kick this off in this example let's copy the contents of the faq module located in ptn\modules\faqs
and add it to the newly created folder within your imports as it is the simplest.
This should include:
- faq-list.xml
- FAQ.xml
- FAQList.xsl
- faqs.scss
- manifest.xml
After they have been copied into the folder that you have created you're going to want to start editing all these files and replacing any reference to FAQ
to a related name that you've called you're bespoke module.
You're also going to want to make the changes to the file that is necessary for the information that's going to be imported.
As a warning, you're going to need to keep the name of manifest.xml
but there will be names within that you will need to be changed to reflect the new naming scheme for the other files.
After you've made all of the necessary changes that you need you will need to navigate to the InstalledModules.xsl
file so that the new module that you've created has been included. It should look something like this:
<xsl:import href="../modules/[BespokeModuleName]/[BespokeModuleName].xsl"/>
Now that the module has been created it's time to add it to a page and test it.
Firstly you're going to want to run your project and navigate to the page that you would like to add the module to.
Once your on the page, in the main area you are going to want to select the edit button which will display all of the different items that you can add to your page.
You now are going to select the bespoke module that you just created and add it to the page.
Congratulations you have now created and added a bespoke module to you web page!
You can create templates in the xsl file that will be able to handle the data that is coming in from your xForms. For example, here I'm taking the content that is being passed through the example XML and handling it in my xsl.
<!-- Example Brief -->
<xsl:template match="Content[@type='example']" mode="displayBrief">
<xsl:param name="sortBy"/>
<xsl:param name="crop"/>
<xsl:param name="class"/>
<xsl:param name="parentId"/>
<xsl:param name="linked"/>
<xsl:param name="itemLayout"/>
<xsl:param name="heading"/>
<xsl:param name="title"/>
<xsl:variable name="parentURL">
<xsl:apply-templates select="." mode="getHref"/>
</xsl:variable>
<div class="listItem examples">
<xsl:apply-templates select="." mode="inlinePopupOptions">
<xsl:with-param name="class" select="'listItem'"/>
<xsl:with-param name="sortBy" select="$sortBy"/>
</xsl:apply-templates>
<div class="lIinner">
<xsl:choose>
<xsl:when test="$title!='' and $heading!=''">
<xsl:variable name="headingNo" select="substring-after($heading,'h')"/>
<xsl:variable name="headingNoPlus" select="$headingNo + 1"/>
<xsl:variable name="listHeading">
<xsl:text>h</xsl:text>
<xsl:value-of select="$headingNoPlus"/>
</xsl:variable>
<xsl:element name="{$listHeading}">
<xsl:attribute name="class">
<xsl:text>title</xsl:text>
</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$heading=''">
<h3 class="title">
<xsl:value-of select="@name"/>
</h3>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$heading}">
<xsl:attribute name="class">
<xsl:text>title</xsl:text>
</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<div class="entryFooter">
<xsl:apply-templates select="." mode="displayTags"/>
<xsl:apply-templates select="." mode="moreLink">
<xsl:with-param name="link" select="$parentURL"/>
<xsl:with-param name="stretchLink" select="$linked"/>
<xsl:with-param name="altText">
<xsl:value-of select="Headline/node()"/>
</xsl:with-param>
</xsl:apply-templates>
<xsl:text> </xsl:text>
</div>
<div class="backTop">
<a href="#pageTop" title="Back to Top">Back To Top</a>
</div>
</div>
</div>
</xsl:template>
In the example previously presented I'm taking in the data from the XML example.xsl
and handling it so that the I am getting the Heading and displaying it if there is one, getting the title and displaying it if there is one, creating a button that links to the parentURL
and creating an a tag that takes you back to the top of the page.
This is a template that can be created and then used again multiple times.
You might have noticed that I have set the mode of the template in my previous example to display brief, this is a value that Protean handles. This means that the template will be used to show the data in a card format on the content detail, which is what I will go over next.
The displayBrief can be used in a multitude of ways, you can use it to simply create content to be displayed and read to the user such as small articles and user profiles. However, they would be most commonly used to create link to other pages, as long as you have a relation in the .XML to another page you can utilize the parentURL to simply navigate straight to the page from from the display brief.
The best way to describe the content detail would be that it is what houses the display briefs within a section on a page. For example, here I'm using the example.xml
for the data that I'm getting and setting the mode to Content Detail
. I'm also getting the heading, title, and display them on the page.
<!-- Example Detail -->
<xsl:template match="Content[@type='example']" mode="ContentDetail">
<xsl:variable name="thisURL" select="/Page/Menu/descendant-or-self::MenuItem[@id=/Page/@id]/@url"></xsl:variable>
<xsl:variable name="debugMode">
<xsl:call-template name="getXmlSettings">
<xsl:with-param name="sectionName">web</xsl:with-param>
<xsl:with-param name="valueName">debug</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<div class="detail examples">
<xsl:apply-templates select="." mode="inlinePopupOptions">
<xsl:with-param name="class" select="'detail newsarticle'"/>
</xsl:apply-templates>
<div class="row">
<div class="col-lg-8">
<h1 class="detail-title" itemprop="headline">
<xsl:apply-templates select="." mode="getDisplayName" />
</h1>
<span class="strapline-detail" itemprop="description">
<xsl:apply-templates select="Strapline/node()" mode="cleanXhtml"/>
</span>
<div class="description entry-content" itemprop="text">
<xsl:apply-templates select="Body/node()" mode="cleanXhtml"/>
</div>
<xsl:apply-templates select="Content[@type='example']" mode="displayBrief"/>
<div class="entryFooter">
<xsl:if test="Content[@type='Tag']">
<div class="tags">
<xsl:apply-templates select="Content[@type='tag']" mode="displayBrief"/>
<xsl:text> </xsl:text>
</div>
</xsl:if>
<xsl:apply-templates select="." mode="backLink">
<xsl:with-param name="link" select="$thisURL"/>
<xsl:with-param name="altText">
<xsl:call-template name="term2006" />
</xsl:with-param>
</xsl:apply-templates>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
</div>
</xsl:template>
You might also be able to catch that I'm applying the template for the example.xsl
displayBrief
so that they are able to be displayed on the ContentDisplay
and repeated for the amount of data that you have.