Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

It is good practice to create a static HTML prototype first. It gives you an overview of the page you need to build.

Download the prototype and extract it to my-first-website-tutorial/light-modules/one-pager-module/webresources/prototype.

...

  • Navigation
  • Intro
  • Three content sections, one of which has a collection of cars
Code Pro
languagexml
titleprototype.html
collapsetrue
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/webresources/prototype/prototype.html?at=master&raw
 

Open the file in your browser. Or go to http://localhost:8080/magnoliaAuthor/.resources/one-pager-module/webresources/prototype/prototype.html to have Magnolia serve it.

...

Create the file one-pager-module/templates/pages/main.yaml

Code Pro
language

...

yaml
titlemain.yaml

...

templateScript: /one-pager-module/templates/pages/main.

...

 

Dialog definition

Define a page dialog. The dialog defines properties which are stored on the page node:

  • Title 
  • Subtitle
  • Copyright
  • Meta description
  • Meta keywords
  • Background image of the intro section

...

ftl
renderType: freemarker
visible: true
title: One pager template
dialog: one-pager-module

...

:pages/main
areas:
  content-sections:
#     availableComponents:
#       content-items-list:
#         id: one-pager-module:components/content-items-list
#       textImage:
#         id: one-pager-module

...

:components/textImage

Lines 8-12: The section availableComponents of the content-sections areas is commented for the time being. We will come back to this when adding components.

Dialog definition

Define a page dialog. The dialog defines properties which are stored on the page node:

  • Title 
  • Subtitle
  • Copyright
  • Meta description
  • Meta keywords
  • Background image of the intro section

...

 

...

Code Pro
language

...

yaml
titleone-pager-module/dialogs/

...

pages/main.yaml
linenumberstrue
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/dialogs/

...

pages/main.yaml?at=master&raw
 

Template script

Create a template script in Most dialogs have Save and Cancel actions. Create a reusable dialog definition file for them. Save this file in /one-pager-module/templates/pages/main.ftlincludes/default-dialog-actions.yaml.

Code Block
languagexmlyaml
titlemain.ftlone-pager-module/includes/default-dialog-actions.yaml
linenumberstrue
collapsetrue
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/raw/light-modules/one-pager-module/includes/default-dialog-actions.yaml?at=master
 

The !include directive is one possibility to reuse configuration. If you have created the includable fragment after the creation of the file which does include it, save the latter again to force the YAML parser to properly register the dialog definition.

Also read YAML - include for further details.

Template script

Create a template script in one-pager-module/templates/pages/main.ftl.

Code Block
languagexml
titlemain.ftl
linenumberstrue
collapsetrue
[#assign title = content.title!"Eric's Classic Cars"]
<!DOCTYPE html>
<html lang="en">
<head>[#assign title = content.title!"Eric's Classic Cars"]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="keywords" content="${content.keywords!""}"/>
    <meta name="description" content="${content.description!""}"/charset="utf-8">
    <meta namehttp-equiv="authorX-UA-Compatible" content="IE=edge">

    <title>${title}</title>

    [#--bootstrap css--]<meta name="viewport" content="width=device-width, initial-scale=1">
    <link<meta relname="stylesheetkeywords" hrefcontent="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/bootstrap.min.css "content.keywords!""}"/>
    <link<meta relname="stylesheetdescription" hrefcontent="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/bootstrap-theme.min.css ">content.description!""}"/>
    <meta name="author" content="">

    <title>${title}</title>

    [#--Custombootstrap CSScss--]
    <link rel="stylesheet" href="${ctx.contextPath}/.resources/one-pager-module/webresources/css/onebootstrap-pager.css?z=123">
    <link href="http://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic"3.3.5/bootstrap.min.css ">
    <link rel="stylesheet" typehref="text/css">
    [#--HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries--]
    <!--[if lt IE 9]${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/bootstrap-theme.min.css ">
    [#--Custom CSS--]
    <link rel="stylesheet" href="${ctx.contextPath}/.resources/one-pager-module/webresources/css/one-pager.css?z=123">
    <script<link srchref="httpshttp://ossfonts.maxcdngoogleapis.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css">
    [#--HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries--]
    <![endif]----[if lt IE 9]>
     [@cms.page /]
</head>
<body>
  <h1>${title}</h1>
  <p>${content.subTitle!"No subtitle defined"}</p>

    [#--jquery and bootstrap js--]<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/jqueryhttps://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
   <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/bootstrap.min.js"></script>
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/jquery.easing.min.js"></script> [@cms.page /]
</head>
<body>
  <h1>${title}</h1>
  <p>${content.subTitle!"No subtitle defined"}</p>

    [#--customjquery and bootstrap js--]
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/jswebresources/onebootstrap-pager.js"></script>
</body>
</html>

Note the following things:

  • Lines 1, 12, 28: We create a Freemarker variable title and assign the page title to it using the content rendering context object. We use the variable in the <title> and <h1> tags.
  • Lines 8, 9: Expressions ${content.keywords!""} and ${content.description!""} for the respective meta tags.
  • References to JavaScript and CSS files from Bootstrap and jQuery.
  • Line 18: Resource reference ${ctx.contextPath}/.resources/one-pager-module/webresources/css/one-pager.css. This file does not yet exist.

Copy resource files

Copy resource files to the folders the script references.

...

3.3.5/jquery.js"></script>
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/bootstrap.min.js"></script>
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources/bootstrap-3.3.5/jquery.easing.min.js"></script>
    [#--custom js--]
    <script src="${ctx.contextPath}/.resources/one-pager-module/webresources

...

  • bootstrap-theme.min.css
  • bootstrap.min.css
  • bootstrap.min.js
  • jquery.easing.min.js
  • jquery.js
/js/one-pager.js"></script>
</body>
</html>

Note the following things:

  • Lines 1, 12, 28: We create a Freemarker variable title and assign the page title to it using the content rendering context object. We use the variable in the <title> and <h1> tags.
  • Lines 8, 9: Expressions ${content.keywords!""} and ${content.description!""} for the respective meta tags.
  • References to JavaScript and CSS files from Bootstrap and jQuery.
  • Line 18: Resource reference ${ctx.contextPath}/.resources/

...

  • one-pager-module/webresources/

...

  • css/one-pager.css. This file does not yet exist.

Copy resource files

Copy resource files to the folders the script references.

  1. Create the folder /.js to one-pager-module/webresources/js/.
  2. Edit one-pager.cssRemove the line  background: url(imgs/intro-bg.jpg) no-repeat center center;  from the .intro-section.

Make the template available

One way to make a template available would be adding a new node to the list of available templates in the Site definitions app. This is the same procedure as the one followed in the Hello Magnolia tutorial:

  1. Go to Magnolia and click WebDev > Site at the bottom of the page. 
  2. In the Site definitions tab, select templates/availability/templates.
  3. Add a content node called one-pager.
  4. Add a property called id with the value one-pager-module:pages/main to the node.

...

  1. bootstrap-3.3.5 and copy the following files from the prototype into the folder:
    • bootstrap-theme.min.css
    • bootstrap.min.css
    • bootstrap.min.js
    • jquery.easing.min.js
    • jquery.js
  2. Copy  one-pager-module/webresources/prototype/one-pager.css  to  one-pager-module/webresources/css/ .
  3. Copy one-pager-module/webresources/prototype/one-pager.js to one-pager-module/webresources/js/.
  4. Edit one-pager.cssRemove the line  background: url(imgs/intro-bg.jpg) no-repeat center center;  from the .intro-section.

Create a page

Now try to create a page in the Pages app with the new "One pager template" template.

...

We introduce the built-in Freemarker directive has_content. We use the built-in to check if the user entered a subtitle. If there is no content we don't need to create the <h3> element at all.

Replace this:

Code Block
languagexml
titletemplates/pages/main.ftl
<h1>${title}</h1>
<p>${content.subTitle!"No subtitle defined"}</p>

 element at all.

Replace this:

Code Block
languagexml
titletemplates/pages/main.ftl
<h1>${title}</h1>
<p>${content.subTitle!"No subtitle defined"}</p>

With this:

Code Pro
languagexml
titletemplates/pages/main.ftl
sections%%(<div class="intro-section" id="intro">)%% - %%(eof: intro-section)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates/pages/main.ftl?at=master&raw
 

Refresh the Magnolia page to see the effect.

Background image

Display a background image in the intro section. Add the following snippet inside the <head> element in the template scriptWith this:

Code Pro
languagexml
titletemplates/pages/main.ftl
sections%%(

...

<style>)%% - %%(

...

</style>)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse

...

/light-modules/one-pager-module/templates/pages/main.ftl?at=master&raw
 

Open the page properties dialog and go the Background tab to select an image. You can find the Jaguar image you see above in /cars/007-cars/intro-bg.jpg in the Magnolia DAM or upload your own.

Navigation

The prototype contains two in-page navigation menus, one at the top and one at the bottom of the page. If you study the html you realize that both menus contain very similar code. Let's remove this duplication and "outsource" the menu code to a Freemarker macro and use it twice.

createSectionNav macro

Create a macro that renders a list of anchor links. The anchors are page areas that you will create in a moment. 

Add the following snippet at the top of the template script:

Code Pro
languagexml
titletemplates/pages/main.ftl
sections%%(macro createSectionNav)%% - %%(#macro])%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates/pages/main.ftl?at=master&raw
 

Top navigation

Call the macro at the top of the page to create a top menu.

Add the following snippet right after the opening <body> tag.

...

 

...

Background image

Display a background image in the intro section. Add the following snippet inside the <head> element in the template script:

Code Pro
languagexml
titletemplates/pages/main.ftl
sections%%(<style>)%% - %%(</style>)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates/pages/main.ftl?at=master&raw
 
Open the page properties dialog and go the Background tab to select an image. You can find the Jaguar image you see above in /cars/007-cars/intro-bg.jpg in the Magnolia DAM or upload your own.

Navigation

The prototype contains two in-page navigation menus, one at the top and one at the bottom of the page. If you study the html you realize that both menus contain very similar code. Let's remove this duplication and "outsource" the menu code to a Freemarker macro and use it twice.

createSectionNav macro

Create a macro that renders a list of anchor links. The anchors are page areas that you will create in a moment. 

Add the following snippet at the top of the template script:

Code Pro
languagexml
title

...

top navigation
sections%%(

...

top navigation)%% - %%(

...

eof: top navigation)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates/pages

...

/main.ftl?at=master&raw
 

Note the macro calls [@createSectionNav page=content areaName="content-sections" type="top" /]. The macro takes the following parameters:

  • page: content of the page as a ContentMap.

  • areaName: name of the area definition node.

  • type: location of the menu, top or bottom.

Footer

...

 

...

navigation

Call the macro at the top of again in the page footer to create a top bottom menu.

Add the following snippet right after the opening <body> tag.before the closing </body> tag and before the <script> elements:

Code Pro
languagexml
title

...

templates/pages/main.ftl
sections%%(

...

--Footer--)%% - %%(--eof:

...

Footer--)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates

...

/pages/main.ftl?at=master&raw
 

content-sections area

The page template defines one area – content-sections.

...

 

...

  • page: content of the page as a ContentMap.

  • areaName: name of the area definition node.

  • type: location of the menu, top or bottom.

Footer navigation

Call the macro again in the page footer to create a bottom menu.

Add the following snippet before the closing </body> tag but before the <script> elements:

Code Pro
language

...

yaml
titletemplates/pages/main.

...

yaml
areas:
  content-sections:
    availableComponents:
#      content-items-list:
#        id: one-pager-module:components/content-items-list
#      textImage:
#        id: one-pager-module

...

:components/textImage 

We haven't rendered the area on the page yet. Add the following snippet between the intro and the footer section:

...

 

content-sections area

The page template defines one area – content-sections.

Code Pro
language

...

xml
titletemplates/pages/main.

...

ftl
sections%%(

...

eof: intro-section)%% - %%(

...

--Footer--)%%
urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/browse/light-modules/one-pager-module/templates/pages/main.

...

ftl?at=master&raw
 

Template script final version

Here you can see the final version of the template script - the way it should like - after you have followed all the above steps.We haven't rendered the area on the page yet. Add the following snippet between the intro and the footer section:

Code Pro
language

...

yaml
titleone-pager-module/templates/pages/main.ftl
linenumberstrue

...

collapsetrue

...

urlhttps://git.magnolia-cms.com/projects/DOCUMENTATION/repos/my-first-website-tutorial/

...

raw/light-modules/one-pager-module/templates/pages/main.ftl?at=master

...


Files overview 

You should now have the following files for the page template:

Code Block
languagebash
light-modules/
└── one-pager-module
    ├── README.md
    ├── dialogs
    │   ├── commoncomponents   └── pages
   └── default-dialog-actions.yaml
       └── pagesmain.yaml
    ├── includes
       └── maindefault-dialog-actions.yaml
    ├── templates
    │   ├── components
    │   └── pages
    │       ├── main.ftl
    │       └── main.yaml
    └── webresources
        ├── bootstrap-3.3.5
        │   ├── bootstrap-theme.min.css
        │   ├── bootstrap.min.css
        │   ├── bootstrap.min.js
        │   ├── jquery.easing.min.js
        │   └── jquery.js
        ├── css
        │   └── one-pager.css
        ├──└── js
            └── one-pager.js

You can download the complete one-pager-module directory as a ZIP from our Git server. It also includes the prototype which is not shown on the files tree above.

Components and the files shown previously from the prototype directory are not shown here. 


Next: Accessing content on the server side