Creating template based pages and layout in Wappler with NodeJS

When creating a website usually you want to include common elements like header/menu and a footer on all you pages. This was possible until now using SSI (server side includes) but this technique requires you to add your SSI on every page you create.

With the new template based pages you can setup a main layout, which includes all your common elements and use it to create your site pages. This way you don’t have to include SSI on all the pages you create, as they will just use what’s included on the layout page (template).
It’s easy to apply changes across your site, as the changes you make on your layout page will be applied automatically to all your pages.

Creating a Layout Page

In your NodeJS project, open the Files Menu:

Under Pages, select layouts (1) and click the add new button (2):

Add a name for this layout page. Note that this name will be used as a file name. We call it main:

Then, add some description for this layout if you need and click the Save button:

Our Layout Page called main has been created. Click it in order to open it in Design View:

The Layout Page contains an area called Content Page. This area will be used to show the content of the content pages, which you create using this layout:

This area is not editable, you can add content before or after it. So let’s add a Navbar and Footer to our layout. They will be added to all the pages created using this layout.

Select the Content Area and click the Add Before button:

You can either create the navbar yourself or use any of the predefined navbars in the Blocks section:

Our navbar has been added. Now let’s add a footer.
Select the Content Area and click the Add After button:

Again we use the predefined blocks for it, but you can add whatever content you need:

Our Layout Page is done. It contains a Header and Footer, which will be added to all the pages we create using it and a content area, where the content of the different pages will be displayed.

Creating a Content Page

Now as we have our main layout created, we can create as many content pages as we need.
In the Files Panel, under Pages select Pages /views (1) and click the Add New button (2):

Add a name for your page:

Then open the Layout menu and select the Layout we created earlier:

Add some description, if needed and then click Save:

Open the page we just created by clicking it in the Pages list:

In Design View you will only see your page content. This is what appears inside the Content part of the main layout. Add any content, as you usually do:

We just select one of the available Blocks:

The content has been added:

You can add whatever content you need on your page and customize it as you like and save it:

And you are done. You can preview the page in your browser:

And you can see the header and footer we included in our layout page have been added to it:

8 Likes

So far so good. Nice implementation!
I finished migrating all my pages to ejs.

Things I’ve noticed so far:

  1. In the page manager(now it makes sense to me) the routes won’t take into account folders. So if I create a folder in views to organize some content pages the routes won’t be generated taking that into account.

  2. Is the partial AC component fully implemented? -> <link rel="wappler-include" type="ejs" href="">
    I tried swapping some <%- include (‘file’) %> for the partial AC component but it didn’t work.

1 Like

We are just getting started - you will see much more goodness in the next update :slight_smile:

2 Likes

2 posts were merged into an existing topic: Docker missing mapping to the new NodeJS views

This is great, I love simple-to-use template engines, makes life so much easier especially for maintenance.

Looking forward to the upcoming goodies :crossed_fingers:

3 Likes

Any plans to inject code into layout head from content?

While content pages may share a layout they need to be able to define independently meta tags or even add certain js/css files that are not needed by other content pages sharing that same layout.

1 Like

Yes, that’s coming into the UI in the next beta :wink: (and it’s available in the code already)

2 Likes

Do I really need to ask(beg)?

1 Like

My other half loves to see grown men beg! :frowning_face:

2 Likes

Here is the code @JonL.
sendJonInjection = happyJon; Break happyJon End

2 Likes

How I read that.

Whatever they do
Break happyJon == !happyJon == sadJon == endOfStory

2 Likes

You will get an option to add a server connect action and custom data to a template route.

If you want to try, the routes file is located at app/config/routes.json.

A template route now looks like:

{
  "path": "/about",
  "routeType": "page",
  "page": "about",
  "layout": "main"
}

Say you want to add metadata to the page, like a title, the json will be:

{
  "path": "/about",
  "routeType": "page",
  "page": "about",
  "layout": "main",
  "data": {
    "title": "About Me"
  }
}

In the template you can then use it as <%= title %>.

But you probably also want to show data from a database, then you need a server connect action that serves that data and use it like:

{
  "path": "/about",
  "routeType": "page",
  "page": "about",
  "layout": "main",
  "data": {
    "title": "About Me"
  },
  "exec": "/api/mydata"
}

exec will be the path to the server action, the data will be available in the template under the data object like <%= data.myvar %>. Some more advanced sample:

<ul>
<% data.query1.forEach(item => { %>
  <li><%= item.title %></li>
<% }) %>
</ul>
2 Likes

As an extra note, the static data is not being passed to the content page when using a layout. The server connect data is being passed to the content page when using a layout. The static data is only available in the master template, the one that is initially loaded. That is a limitation that we currently have, but that can change.

1 Like

Thanks @patrick! Easy peasy lemon squeezy

So if I just want to add specific js files for that route I would do something like this, right?

"data": {
    "js": [
           "file1.js",
           "folder/file2.js",
           "file3.js"
           ]
}
<head>
	<% if (typeof js !== 'undefined') {
	 js.forEach(item => { %>
	<script src="./js/<%= item %>"></script>
	<% })} %>
</head>

Yes, you set the data per route. So can reuse the template for different routes and fill it with different data depending on the route.

1 Like

Hey Patrick, is there room to extend the static/dynamic page/templates feature you’ve added to wappler in order to have static incremental pre-rendered sites a la gatsby/nextjs or there is needed hosting access to CDN’s in order to have this implemented? Or anything else?

Also, will all these features only be for NodeJS or will they be added to PHP, too?

We were actually already discussing something like that, we can use the templates we have now for node to generate static pages. First we will focus on the node and v3 release, after that we will see if a static site generator with templates is possible.

4 Likes

We are also looking at PHP templates, but it is a bit more difficult there since we don’t have full control over the server and routing like with node.

1 Like

I’m seeing an incredibly fast-paced pattern of NodeJS being nowhere a month ago to being the primary and recommended framework today.

1 Like