Main  /  Edit  /  History  /   /  Users Area

Views Inheritance

Introduction

CppCMS views are actually classes, and thus you can derive one view from other, override different templates and so on.

This gives a developer a very powerful tool to design HTML templates.

For example, we create a master view that includes basic CSS and HTML style, and defines placeholders for different types of content that should be included. Then we derive different views that are responsible for the actual content.

     master
   /    |   \
news  page  intro

Of course the content for the derived views should be also be derived from the parent content classes.

Content

Let's create our content.h for the sample hierarchy above.

First we define our master content in the content namespace.

struct master : public cppcms::base_content {
    std::string title;
};

It would include shared information like our web site title.

Then we create a news content derived from the master:

struct news : public master {
    std::list<std::string> news_list;
};

It would add some set of "news" messages we want to display.

We do the same for page content with, of course, different data:

struct page : public master {
    std::string page_title, page_content;
};

For the "introduction" page we will use the same master content, as we don't need more data.

Views

Master

Let's show our master.tmpl:

As usual we define the include and the skin name:

<% c++ #include "content.h" %>
<% skin myskin %>

Then we define our master view

<% view master uses content::master %>

We create some generic title that can be overridden.

<% template title() %><%= title %><% end %>

Define the real content we want to display

<% template page_content() %>Override  Me<% end %>

And finally we define our main render function

<% template render() %>
<html>
<head>
    <title><% include title() %></title>
</head>
<body>
<h1><% include title() %></h1>
<div id="content">
<% include page_content() %>
</div>
</body>
</html>
<% end template %>

Note:

Then we finish our master.tmpl as usual

<% end view %>
<% end skin %>

News

Then we create our news.tmpl. As usual we start and end it with

<% skin myskin %>
...
<% end skin %>

Then we define our view:

<% view news uses content::news extends master %>

Note:

Then we override the title:

<% template title() %>
    <% include master::title() %> :: News
<% end %>

And define our central content:

<% template page_content() %>
<% foreach message in news_list %>
    <ul>
    <% item %>
        <li><%= message %></li>
    <% end %>
    </ul>
<% end foreach %>
<% end template %>

Page

We do the same for page.tmpl

<% skin myskin %>
<% view page uses content::page extends master %>

<% template title() %>
    <% include master::title() %> :: <%= page_title %>
<% end %>

<% template page_content() %>
    <%= page_content | raw %>
<% end template %>

<% end view %>
<% end skin %>

Introduction

Now we create our final intro view. However in its case, we do not add any new content as we don't need it. Therefore we reuse content::master.

<% skin myskin %>
<% view intro uses content::master extends master %>

<% template page_content() %>
    <p><a href='<% url "/page" %>'>The Page</a></p>
    <p><a href='<% url "/news" %>'>The News</a></p>
<% end template %>

<% end view %>
<% end skin %>

Note: we use <% url ... %> tag from the templates the same way we used it from the application in this tutorial.

Controller

We create a usual mapping to intro, news and page functions:

dispatcher().assign("",&myapp::intro,this);
mapper().assign("");

dispatcher().assign("/news",&myapp::news,this);
mapper().assign("news","/news");

dispatcher().assign("/page",&myapp::page,this);
mapper().assign("page","/page");

mapper().root("/myapp");

Please note, because there is no direct HTML page that renders master content we do not create a mapping for it. On the other hand we do want to setup the shared master content for all links. So we create a small function that initializes the content:

void ini(content::master &c)
{
    c.title = "My Web Site";
}

Then we define our "pages":

void intro()
{
    content::master c;
    ini(c);
    render("intro",c);
}
void page()
{
    content::page c;
    ini(c);
    c.page_title = "About";
    c.page_content = "<p>A page about this web site</p>";
    render("page",c);
}
void news()
{
    content::news c;
    ini(c);
    c.news_list.push_back("This is the latest message!");
    c.news_list.push_back("This is the next message.");
    c.news_list.push_back("This is the last message!");
    render("news",c);
}

Notes:

Building

Please note, even thought each view has its own file the order of compilation is important so the page.tmpl would be compiled after master.tmpl. So in our Makefile we write:

cppcms_tmpl_cc master.tmpl page.tmpl news.tmpl intro.tmpl -o my_skin.cpp

It would not work if master.tmpl were not the first in the list.


Applications Hierarchy | Top | Working With Forms

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page



Valid CSS | Valid XHTML 1.0