Main  /  Edit version 7  /  Edit version 8  /   /  Users Area

Difference "Templates: Top Level Blocks (v 1.x)" ver. 7 versus ver. 8

Content:

<!--toc-->
## General notes
Each block begins with its definition and ends with the special command `end`.
'end' [ 'skin' | 'view' | 'template' ]
This command may optionally include the block type after it. For example:
<% skin myskin %>
<% view master uses data %>
...
<% end view %>
<% end %>
Above, we closed `view` using its specification but we closed `skin` without specifying its block type.
## skin
### Syntax:
'skin' [NAME]
It is the topmost command in every template.
The name of the `skin` can be specified or omitted in which case its name should be defined externally during the build process using the switch `-s`.
### Notes
- If all the templates you create within one skin will not share any parts with other skin, specify the skin's name, otherwise use blank and pass its name using the switch.
- If you pass the skin name using the switch `-s`, it should
match the name of the skin you use in the skin command.
- You can't use more then one skin name in the same `cppcms_tmpl_cc` compilation.
**For example:**
Correct Example 1:
foo.tmpl:
<% skin foo %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl -s foo
Correct Example 2:
foo.tmpl:
<% skin foo %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl
Correct Example 3:
foo.tmpl:
<% skin %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl -s foo
Correct Example 4:
foo.tmpl:
<% skin %>
...
<% end %>
bar.tmpl:
<% skin foo %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl bar.tmpl -s foo
Wrong - two different skins in the same compilation:
foo.tmpl:
<% skin foo %>
...
<% end %>
bar.tmpl
<% skin bar %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl bar.tmpl
Wrong - unknown skin name:
foo.tmpl:
<% skin %>
...
<% end %>
cppcms_tmpl_cc foo.tmpl foo.tmpl
## view
### Syntax:
'view' NAME 'uses' IDENTIFIER ['extends' NAME]
'view' NAME 'uses' IDENTIFIER ['extends' NAME] [ 'abstract' ] [ 'inline' ] // since 1.2
Creates a new view (C++ class) that is responsible for rendering a specific type of content pages. `'uses' IDENTIFIER` specifies the type of the content (some object derived from `cppcms::base_content`) that this view should render. It actually defines `content` reference member of this type.
Note: in some cases, you may have to access `content` members directly.
You can specify `'extends' NAME` if you want the view to inherit from another view.
_Since 1.2_:
- `abstract` - this view or its parent contains pure virtual templates - it is impossible to create one - used for plugins.
- `inline` - put the code of the C++ class in the header - useful for deriving from this view in plugins
### Derivation restrictions
When you create a derived view, the content of the child should be derived from the content of its parent as well.
For example:
<% view master uses data::master %>
..
<% end view %>
<% view page uses data::page extends master %>
...
<% end view %>
Then, `data::page` _must_ be derived from `data::master`.
_Rationale:_
When you create the `master` parent you need to provide its own content as well. It also receives its child content, thus it works only if the child content is derived from the parent content.
### Generated Code
The generated code for the above two examples would approximately look like this:
struct master :public cppcms::base_view
{
data::master &content;
master(std::ostream &_s,data::master &_content):
cppcms::base_view(_s),
content(_content)
{
}
...
}; // end of class master
struct page :public master
{
data::page &content;
page(std::ostream &_s,data::page &_content):
master(_s,_content),
content(_content)
{
}
...
}; // end of class page
## template
A template corresponds to a member function of a view class.
### Syntax
The definition of template consists of its name, round brackets and an optional, comma separated list of parameters:
'template' NAME '(' [ parameter [',' parameter ... ] ] ')'
'template' NAME '(' [ parameter [',' parameter ... ] ] ')' [ = 0 ] // since 1.2
Where each `parameter` is:
IDENTIFIER ['const' ] ['&'] NAME
For example:
<% template render() %>
<% template show_list(data::list_t const &list) %>
<% template show_numbers(int x,int y, double z) %>
Note: you can not specify template parameters like `list<int>`. You should define a type for them.
_Since 1.2:_ it is possible to create pure virtual template by adding `= 0`. The template that must be implemented by derived view to be creatable. Note: the view should be defined as `abstract`
### Generated Code
Each template is translated to a virtual member function of the class it is defined in. This function
returns `void` and receives defined parameters, thus, `show_list` in the above example would be
translated to:
virtual void show_list(data::list_t const &list)
{
...
}
<h1>include <iostream></h1> <h1>include <string></h1> <h1>include <cstring></h1>

include <sys/socket.h>

include <netinet/in.h>

include <unistd.h>

int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address);

// HTML content to be served
std::string html = 
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<!DOCTYPE html>"
    "<html>"
    "<head><title>My C++ Web</title></head>"
    "<body><h1>Welcome to a Simple Web Page!</h1><p>This is served from C++.</p></body>"
    "</html>";

// Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
    perror("socket failed");
    exit(EXIT_FAILURE);
}

// Bind
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
    perror("bind failed");
    exit(EXIT_FAILURE);
}

// Listen
if (listen(server_fd, 3) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
}

std::cout << "Server is running on http://localhost:8080" << std::endl;

while (true) {
    // Accept client
    client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
    if (client_fd < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    char buffer[3000] = {0};
    read(client_fd, buffer, 3000);  // Read client request

    std::cout << "Request:\n" << buffer << std::endl;

    // Send response
    send(client_fd, html.c_str(), html.size(), 0);
    close(client_fd); // Close connection
}

return 0;

}

<h1>include <iostream></h1> <h1>include <string></h1> <h1>include <cstring></h1>

include <sys/socket.h>

include <netinet/in.h>

include <unistd.h>

int main() { int server_fd, client_fd; struct sockaddr_in address; int addrlen = sizeof(address);

// HTML content to be served
std::string html = 
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n\r\n"
    "<!DOCTYPE html>"
    "<html>"
    "<head><title>My C++ Web</title></head>"
    "<body><h1>Welcome to a Simple Web Page!</h1><p>This is served from C++.</p></body>"
    "</html>";

// Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
    perror("socket failed");
    exit(EXIT_FAILURE);
}

// Bind
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
    perror("bind failed");
    exit(EXIT_FAILURE);
}

// Listen
if (listen(server_fd, 3) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
}

std::cout << "Server is running on http://localhost:8080" << std::endl;

while (true) {
    // Accept client
    client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
    if (client_fd < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    char buffer[3000] = {0};
    read(client_fd, buffer, 3000);  // Read client request

    std::cout << "Request:\n" << buffer << std::endl;

    // Send response
    send(client_fd, html.c_str(), html.size(), 0);
    close(client_fd); // Close connection
}

return 0;

}


Navigation

Main Page


Valid CSS | Valid XHTML 1.0