Main  /  Edit version 2  /  Edit version 3  /   /  Users Area

Difference "Views Inheritance" ver. 2 versus ver. 3

Content:

<!--toc-->
## 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 described. Then we derive different views that are responsible on actual content.
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 actual content.
master
/ | \
news page intro
Of course the content for the derived views should be also
be derived of the parent content classes.
## Content
Let's create our `content.h` for the sample hierarchy above.
First we define our `master` content in `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:
struct page : public master {
std::string page_title, page_content;
};
With, of course, different data. For the "introduction" page
we would use the same `master` content as we would
not 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:
- We use `title()` in several places
- We put our placeholders in the locations we want, in our
case it is one placeholder `page_content()`
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:
- It `extends master` - i.e. derived from `master` view
- It uses `content::news` and because `content::news` derived from `content::master` it works.
Then we override a title using original 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, but in its case
we do not add any new content as we don't need it - 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](wikipp/en/page/cppcms_1x_tut_url_mapping) 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:**
- Each one of them renders the view it needs
- Each one of then uses their own content
- Each one of them calls shared `ini()` function
to setup the `master` content for all.
## 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 of `master.tmpl` would not be the
first in the list.

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