## Table of Contents |
|
- [Roles](#roles) |
- [Constructors](#ctor) |
- [Public Members](#memb) |
- [Public Member Functions](#membf) |
|
- [HTTP Headers](#hdr) |
- [Localization](#loc) |
- [Templates rendering](#rend) |
|
- [cppcms::application member functions](#application) |
|
- [Virtual Member functions](#vmemb) |
- [Public Template Member Functions](#templmeb) |
|
|
## <span id="roles"></span>Roles |
|
`worker_thread` and `application` are very similar classes that gives user similar APIs but they have important differences: |
|
`worker_thread` has single instance in each worker thread or process, it is usually not used directly, but it is referenced by several `application` classes. |
|
In many cases, we need to have more then one application or sub application in our process (for example wiki and forum or users panel and administration panel). |
|
All these application share same controls like access to cache and sessions, access for HTTP requests --- all these stored in `worker_thread` class. |
|
In terms of API, both classes are very similar with the difference that `worker_thread` stores actual data and `application` stores references to this data in `worker_thread`. |
|
In most of cases developers should derive their own classes |
from `cppcms::application` and not from `cppcms::worker_thread`. |
|
## <span id="ctor"></span>Constructors |
|
worker_thread(manager const &s); |
application(worker_thread &w); |
|
`worker_thread` and `application` constructors should receive a reference to `manager` and primary `worker_thread`. |
|
For example: |
|
class my_application : public application { |
my_application(worker_thread &w) : application(w) { |
... |
|
|
## <span id="memb"></span>Public Members |
|
### cppcms::application |
|
worker_thread &worker; |
url_parser &url; |
manager const &app; |
cgicc::Cgicc *&cgi; |
cgicc::CgiEnvironment const *&env; |
cgicc_connection *&cgi_conn; |
cache_iface &cache; |
session_interface &session; |
ostream &cout; |
boost::signal<void()> &on_start; |
boost::signal<void()> &on_end; |
|
### cppcms::worker\_thread |
|
url_parser url; |
manager const &app; |
cgicc::Cgicc *cgi; |
cgicc::CgiEnvironment const *env; |
cgicc_connection *cgi_conn; |
cache_iface cache; |
session_interface session; |
ostream cout; |
boost::signal<void()> on_start; |
boost::signal<void()> on_end; |
|
### Description |
|
- **`url_parser url`** |
|
It is a class responsible on binding various handlers |
to different requested url. For example: |
|
url.add("^/test$",&app::test,this); |
|
See [`cppcms::url_parser`](/wikipp/en/page/ref_cppcms_url_parser) for reference. |
|
- **`manager const &app`** -- access to [`cppcms::manager`](/wikipp/en/page/ref_cppcms_manager) class. Usually used to fetch configuration values. For example: |
|
int num=app.config.ival("my_app.number"); |
|
- **`cgicc::Cgicc *cgi`** -- access to [`cgicc::Cgicc`](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1Cgicc.html) class of cgicc library that gives you a content of HTTP query. |
|
It is usually used together with form processing: |
|
some_content c; |
c.some_form.load(*cgi); |
|
- **`cgicc::CgiEnvironment const *env`** -- environment of cgicc query. See [`cgicc::CgiEnvironment`](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1CgiEnvironment.html) |
|
- **`cgicc_connection *cgi_conn`** --- access to low level CGI API. Input stream, output stream environment variables. |
|
Generally it should be used only in case we need access to some CGI environment variable unsupported by cgicc. For example: |
|
string encodings=cgi_conn->env("ACCEPT_ENCODING"); |
|
- **`cache_iface cache`** -- access to cache API. See: [`cache_iface`](/wikipp/en/page/ref_cppcms_cache_iface) |
- **`session_interface session`** -- access to sessions API. See: [`session_interface`](/wikipp/en/page/ref_cppcms_session_iface) |
|
- **`ostream cout`** --- the stream for output content of the cgi process (without headers). It is generally used via templates system, however it can be used directly for creating HTML or any other output content. |
|
For example, create csv: |
|
set_header(new HTTPContentHeader("text/csv")); |
cout<<"n,n!"<<endl; |
cout<<"0, 1"<<endl; |
cout<<"1, 1"<<endl; |
cout<<"2, 2"<<endl; |
cout<<"3, 6"<<endl; |
|
- **`boost::signal<void()> on_start, on_end`** --- these are the signals that application can connect itself in order to perform certain tasks when new query comes, independently from URL. |
|
Various application running in same thread may attach |
many signals. |
|
For example: |
|
class my_app: public application { |
|
int user_id; |
string user_name; |
void start() |
{ |
if(session.is_set("user_id")) { |
user_id=session.get<int>("user_id"); |
user_name=fetch_user_name(user_id); |
} |
else { |
user_id=-1; |
user_name="visitor"; |
} |
} |
void end() |
{ // Cleanup all user data |
user_id=0; |
user_name.clear(); |
} |
... |
my_app() |
{ |
on_start.connect(bind(&start,this)); |
on_end.connect(bind(&end,this)); |
... |
} |
|
**Note:** callbacks connected to `on_end` should never throw -- think of them as of destructors. |
|
|
## <span id="membf"></span>Public Member Functions |
|
### <span id="hdr"></span>HTTP Headers |
|
- **`void set_header(cgicc::HTTPHeader *h)`** -- set newly created HTTP Header. |
|
Notes: |
|
1. Default header is `cgicc::HTTPHTMLHeader`. |
2. It removes previous header and all cookies associated with it. Thus, always set header and then set cookies. |
3. The pointer to header is freed by an application. |
|
For example: |
|
set_header(new HTTPContentHeader("text/csv")); |
|
See [cgicc::HTTPHeader](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1HTTPHeader.html) for details. |
|
- **`void set_cookie(cgicc::HTTPCookie const &c)`** --- set HTTP Cookie to current header. |
|
See: [cgicc::HTTPCookie](http://www.gnu.org/software/cgicc/doc/classcgicc_1_1HTTPCookie.html) for details of cookies creation. |
|
- **`cgicc::HTTPHeader &header()`** -- return current header. |
- **`void add_header(string s)`** -- add general header. For example: |
|
add_header("X-Sendfile: " + filename); |
|
CgiCC API does not allow rendering several headers together, thus -- `add_header(string)` removes this limitation. For example: |
|
add_header("Status: 302 Found"); |
set_header(new HTTPRedirectHeader(new_location)); |
- **`void set_user_io()`** -- allows user to write directly to output stream instead of internal buffer. |
|
Calling this functions forces saving all session |
data and all headers are immediately written |
to the output stream. Thus, updating session data |
or changing headers would not take an effect. |
|
It can be used for generating big output that |
should not be saved in internal buffers and compressed. |
|
__Note:__ You should use output stream from `cgi_conn` |
instead of ordinary `cout` member of `worker_thread` |
for output. |
|
For example, streaming of image:: |
|
ifstream file("big.png"); |
|
set_header(new cgicc::HTTPContentHeader("image/png")); |
|
set_user_io(); |
ostream &cout=cgi_conn->cout(); |
|
for(;;) { |
file.read(&buffer.front(),1024); |
cout.write(&buffer.front(),file.gcount()); |
if(file.eof()) |
break; |
} |
file.close(); |
|
### <span id="loc"></span>Localization |
|
Setting language dynamically: |
|
- **`void set_lang()`** -- Set default application language. |
- **`void set_lang(string const &)`** -- Set application language. This call affects all other calls of `gettext()`, `ngettext()` and language of template rendering. |
|
Translating strings: |
|
- **`char const *gettext(char const *s)`** -- translate string "s". |
- **`char const *ngettext(char const *s,char const *p,int n)`** -- translate single/plural form of string for `n`. |
|
_Note:_ In contrary to GNU gettext library, these functions are thread safe --- you can use different languages in different threads safely. |
|
Working with different domain: |
|
- **`transtext::trans const *domain_gettext(string const &d)`** -- returns pointer to gettext dictionary for specific domain. `transtext::trans` has two public functions important to user: gettext and ngettext with same signatures as above. |
|
For example: |
|
transtext::trans const *tr=domain_gettext("views"); |
string username=tr->gettext("username"); |
|
This function has no effect on current gettext dictionary. |
|
### <span id="rend"></span>Templates rendering |
|
**Setting skins** |
|
void use_template(string s=""); |
|
Set template. If no specified, default is used. For example: |
|
if(session.is_set("skin")) |
use_template(session["skin"]); |
|
**Rendering output** |
|
void render(string teml,base_content &c); |
void render(string view,string teml,base_content &c); |
void render(string teml,base_content &c,ostream &o); |
void render(string view,string teml,base_content &c,ostream &o); |
|
Render specific function `templ` using content `c`. If `view` specified, render using view `view` instead of default. |
|
If `ostream &o` specified render template to `o` instead of cout. The recent is useful to create partial renderings and caching them. For example: |
|
ostringstream tmp; |
render("sidebar",content,tmp); |
cache.store_frame("sidebar",tmp.str()); |
|
|
## <span id="application"></span>cppcms::application member functions |
|
### <span id="vmemb"></span>Virtual Member functions |
|
**Note:** these functions are used only in `cppcms::application` class where user can override default functionality. They does not exist in `worker_thread` or have different semantics. |
|
- **`virtual void on_404()`** --- default handler that is called in case of URL that does not match any given pattern. |
|
You may display your own page there or redirect to general correct url. |
|
- **`virtual void main()`** --- this is the main function. It has following default implementation: |
|
on_start(); |
if(url.parse()<0) { |
on_404(); |
} |
on_end(); |
|
If you decide to override this function, don't forget ti call `on_start` and `on_end` semantics. For example, you can try to handle there sql connection errors: |
|
|
on_start(); |
for(i=0;i<2;i++) { |
try { |
if(url.parse()<0) { |
on_404(); |
} |
break; |
} |
catch(sql_connection_error &e) |
{ |
if(i==0) |
sql.reconnect(); |
else |
no_connection_page(); |
} |
} |
on_end(); |
|
**Notes:** Only **one** application class may override it's `main()` because only one main function is called. Rest applications working in same thread are called using url bindings. |
|
### <span id="templmeb"></span>Public Template Member Functions |
|
These functions are used for easier connection of |
SQL libraries to an application. Assuming you have persistent SQL connection per thread. |
|
These functions implemented as template functions in order |
to prevent linking with specific libraries. |
|
#### SOCI |
|
template<typename SQL> |
void soci_load(SQL &sql) |
|
Connect to SQL database using [SOCI](http://soci.sourceforge.net/). |
|
_CppCMS Configuration parameters:_ |
|
- `soci.conn` soci connection string calling: `sql.open(conn);` |
- `soci.driver`, `soci.params` -- connect to soci calling: `sql.open(driver,params);` |
|
|
#### DbiXX |
|
template<typename SQL> |
void dbixx_load(SQL &sql); |
|
Connects to database using dbixx library, it uses following parameters: |
|
- `dbixx.driver` --- the SQL driver used for dbixx, for example "sqlite3". |
|
All other parameters are taken from configuration using prefix given in `dbixx.driver`. For example: |
|
dbixx.driver="sqlite3" |
sqlite3.dbname="wikipp.db" |
sqlite3.sqlite3_dbdir="./db/" |
|
Refer to [libdbi-drivers](http://libdbi-drivers.sourceforge.net/docs.html) documentation pages for setting up correct parameters. |
|
|