What is CppCMS ? CppCMS is a free high performance web development framework aimed at rapid web application development.It is different from other development frameworks like Python Django, java Servelets in the following ways;
- It is designed and tuned to handle extremely high loads.
- It uses modern C++ as the primary development language in order to achieve the first goal.
- It is designed for developing both Web Sites and Web Services.
1. config.js
{
"service" : {
"ip":"0.0.0.0",
"api" : "http",
"port" : 8081
},
"http" : {
"script_names" : ["/cppcms"]
}
}
In the configuration,we setup our service to listen on port 8080 using HTTP protocol .We also provide the script_names(/cppcms)
parameter that defines the path to the virtual "CGI Scripts" or in simple words the path that our application should be called from.
2. include
1) site.h
#include <cppcms/application.h>
#include <cppcms/applications_pool.h>
#include <cppcms/service.h>
class Site : public cppcms::application {
public:
Site(cppcms::service &srv);
void Page();
};
cppcms/application.h
- the classapplication
that every CppCMS application is derived from.cppcms/applications_pool.h
- classapplications_pool
- the class that manages user applications - creates new per HTTP request and caches them for future use.cppcms/service.h
- the service - central event loop of the network service.
cppcms::application
. It should receive in its constructor a reference to the central CppCMS service that runs our application. And it's member function
Page()i
s
created for rendering the HTML web page and it's function implementation can be found in the file site.cc.
2)content.h
#ifndef CONTENT_H
#define CONTENT_H
#include <cppcms/view.h>
namespace Content {
struct PageContent : public cppcms::base_content {
};
}
#endif
<cppcms/view.h
>
that will provide us with all the definitions required as a base for our content class.So we've created a small structure
PageContent
that would be rendered with an HTML template.But the
PageConten
t in our project is empty as this is a static web page.
3.template
page.tmpl
<% c++ #include "model/content.h" %>
<% skin page%>
<% view page_view uses Content::PageContent %>
<% template render() %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
</head>
<body>
<h1> Hello World!</h1>
</body>
</html>
<% end template %>
<% end view %>
<% end skin %>
We need to review the render rational of CPPCMS in the backend,namely how to convert the .tmpl to C++ code. That is view. We define the skin view &template in the code above which will be converted into C++ code . See more details below.
First, page_view will be implemented as a class, and it's in the namespace called page(defined by skin).Besides <% template render() %> will be seen as a render member function in the page_view class. Thus the HTML code between <HTML> and </HTML> will be converted to C++ code by function render(). See the result in file page.cc in directory view.
4. page.cc
#line 1 "../template/page.tmpl"
#include "model/content.h"
#line 2 "../template/page.tmpl"
namespace page {
#line 3 "../template/page.tmpl"
struct page_view :public cppcms::base_view
#line 3 "../template/page.tmpl"
{
#line 3 "../template/page.tmpl"
Content::PageContent &content;
#line 3 "../template/page.tmpl"
page_view(std::ostream &_s,Content::PageContent &_content): cppcms::base_view(_s),content(_content)
#line 3 "../template/page.tmpl"
{
#line 3 "../template/page.tmpl"
}
#line 4 "../template/page.tmpl"
virtual void render() {
#line 16 "../template/page.tmpl"
out()<<" \n"
" <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> \n"
" <html> \n"
" <head> \n"
" \n"
" </head> \n"
" \n"
" <body> \n"
" <h1> Hello World!</h1>\n"
" </body> \n"
" \n"
" </html> \n"
" ";
#line 16 "../template/page.tmpl"
} // end of template render
#line 17 "../template/page.tmpl"
}; // end of class page_view
#line 18 "../template/page.tmpl"
} // end of namespace page
#line 19 "../template/page.tmpl"
namespace {
#line 19 "../template/page.tmpl"
cppcms::views::generator my_generator;
#line 19 "../template/page.tmpl"
struct loader {
#line 19 "../template/page.tmpl"
loader() {
#line 19 "../template/page.tmpl"
my_generator.name("page");
#line 19 "../template/page.tmpl"
my_generator.add_view<page::page_view,Content::PageContent>("page_view",true);
#line 19 "../template/page.tmpl"
cppcms::views::pool::instance().add(my_generator);
#line 19 "../template/page.tmpl"
}
#line 19 "../template/page.tmpl"
~loader() { cppcms::views::pool::instance().remove(my_generator); }
#line 19 "../template/page.tmpl"
} a_loader;
#line 19 "../template/page.tmpl"
} // anon
5.src
1)site.cc
#include "controller/site.h"
#include <cppcms/url_dispatcher.h>
#include "model/content.h"
#include <cppcms/http_file.h>
using namespace std;
Site::Site(cppcms::service &srv):cppcms::application(srv) {
dispatcher().assign("/page" , &Site::Page, this);
}
void Site::Page() {
Content::PageContent content;
render("page","page_view", content);
}
Before you read the code in site.cc please learn more details about how to connect different URLs to their associated functions in CppCMS on CppCMS.com.
On line 10, in our constructor, we map a URL to member function.We connect the regular expression /page
to the member function number
of this
instance . So when the web server receives requests that match a script name /page
,the member function Page() in Site would be called.
In the Page() implementation, we define a content object ,and the function render definition is as folllows:
void render(std::string template_name,base_content &content)
We employ it to render the page.tmpl in template.
2)main.cc
<span style="color:#222222;">#include "controller/site.h"
#include "model/content.h"
#include <string>
#include <iostream>
#include <cppcms/mount_point.h>
#include <cppcms/json.h>
#include <stdexcept>
#include <sstream>
using namespace std;
int main(int argc, char ** argv) {
try {
cppcms::service srv(argc, argv);
</span><span style="color:#009900;">//We tell the applications_pool class to use our application - Site - by providing it a predefined object factory cppcms::applications_factory<Site>(). We then so call mount our application to the pool so it will be used for request handling.</span><span style="color:#222222;">
srv.applications_pool().mount(cppcms::applications_factory<Site>());
</span><span style="color:#009900;">//And now we run our event loop.</span><span style="color:#222222;">
srv.run();
}
catch(std::exception const &e) {
std::cerr<<e.what()<<std::endl;
}
}</span>