<!--toc-->
|
|
## Overview
|
|
The process of building CppCMS templates is following:
|
|
1. Compile all sources of specific view together into single C++ file using [cppcms\_tmpl\_cc](/wikipp/en/page/ref_utils#tmpl).
|
2. Compile C++ file into object file.
|
3. Link it together with program or create dynamically loadable object that can be loaded by CppCMS program.
|
|
## Creation of C++ code
|
|
Can be done by invoking [cppcms\_tmpl\_cc](/wikipp/en/page/ref_utils#tmpl) with a list of files, for example:
|
|
cppcms_tmpl_cc -o view.cpp main.tmpl page.tmpl article.tmpl
|
|
Note, when you derive classes from parents, you should compile them together in correct order.
|
|
For example for following hierarchy.
|
|
[master]
|
/ \
|
[page] [summary]
|
/ \ / \
|
[post] [info.] [archive] [recent_posts]
|
|
You should compile files as:
|
|
cppcms_tmpl_cc master.tmpl page.tmpl post.tmpl \
|
info.tmpl summary.tmpl archive.tmpl \
|
recent_posts.tmpl -o my_view.cpp
|
|
When you share some templates between various skins, and compile all then in namespace `vary`. You should specify parameter: `-n view_name`.
|
|
By default, templates compiler puts all translation strings in the domain that is named by template name. So if you compile with `-n skin1` all you strings would be taken from
|
`skin1` domain. It can be overridden by specifying `-d domain_name` switch.
|
|
Generally you want to put all templates to same domain as the main program.
|
|
## How templates are loaded
|
|
Each C++ file that is generated from the template includes
|
static global constructor that registers all classes of specific view in `libcppcms`.
|
|
When programmer wants to use come class from specific view
|
he calls `render()` function of `worker_thread` class that
|
seeks for registered views and uses them.
|
|
Thus, everything you need to do is link this object with your library or load it dynamically.
|
|
## Static Linking with Compiled Object
|
|
This is the simplest way to add the template, for example:
|
|
cppcms_tmpl_cc -o view.cpp master.tmpl ...
|
g++ -O2 -Wall view.cpp -o view.o
|
g++ application_objects.o view.o -lcppcms -o app
|
|
## Using Libraries of Views
|
|
Sometimes, you may create a library of several views and try
|
to link with them. For example:
|
|
g++ -fPIC -DPIC view1.cpp -o view1.o
|
g++ -fPIC -DPIC view2.cpp -o view2.o
|
g++ -shared view1.o view2.o -lcppcms -o libview.so
|
|
Now you link this library directly with your program:
|
|
g++ application_objects.o -L. -lview -lcppcms -o app
|
|
You can also create static library and link with it.
|
|
g++ view1.cpp -o view1.o
|
g++ view2.cpp -o view2.o
|
ar cru libview.a view1.o view2.o
|
ranlib libview.a
|
|
__Now, if you link *static* the library as is, it would not work!!!__ At least with GNU linker.
|
|
GNU linker "optimizes" the code and discovers that there
|
is no symbols in application objects that refer to the
|
symbols of libview.a and would not include it in link process.
|
|
In order to make everything work you should link as following:
|
|
g++ application_objects.o \
|
-Wl,--whole-archive libview.a -Wl,--no-whole-archive \
|
-lcppcms -o app
|
|
It would force the linker include all objects form libview.a and cause everything work correctly.
|
|
_Note:_ You do not need this for dynamically loaded libraries like so or dll. Because, by default they include
|
whole archive.
|
|
## Dynamic Loading of Views
|
|
You have an option load all views dynamically from shared object or dll. This option have following restrictions:
|
|
1. You should compile your program with `--export-dynamic` option, otherwise dynamic casting would not work and you'll get error "incorrect content type" trying to render your views.
|
2. Windows/Cygwin has strong restriction on undefined symbols in dll's. Thus you should not refer directly to any non-virtual member functions of your content objects, otherwise you would get linker errors trying to build dll.
|
|
For example:
|
|
Build your loadable view:
|
|
cppcms_tmpl_cc -o view.cpp master.tmpl ...
|
g++ -fPIC -DPIC view.cpp -o view.o
|
g++ -shared view.o -lcppcms -o libview.so
|
|
Link your program
|
|
g++ --export-dynamic app_objects.o -lcppcms -o app
|
|
Now add to your [configuration file](/wikipp/en/page/ref_utils#tmpl) path to directory where
|
libview.so is placed:
|
|
templates.dirs = { "/usr/local/lib/youapp" }
|
|
When application starts, it would try to load **any** shared
|
object that is placed in this path. Thus, it is not good
|
idea to save put your views into directory with other
|
non-related libraries.
|
|
|