Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Сайт на с (CppCMS). Часть 1

Anna | 24.06.2014 | нет комментариев
Здравствуй высокочтимый %username%.
Сегодня я хотел бы поделиться с тобой личным навыком в создании Web плана на CppCMS (библиотека-шаблонизатор на с ). Дозволено назвать это «поддержкой начинающему программисту на CppCMS».

Для чего писать сайт на с

Аргументы за и вопреки такого решения могут быть крайне многообразны и, что бы не спровоцировать войну «языковых школ», я проведу параллель с автомобилями: «Я приобрел данный. Нравится. Езжу. Продавать не хочу!».
Из дополнительных доводов будет то, что данный язык является профильным для моего рабочего места.

Давайте теснее что-нибудь напишем

Впрочем раньше

Перед написанием сайта — придется вначале оное (CppCMS) поставить на рабочую машину. Библиотека самым наглым образом требует для своей работы Boost c , pcre, crypt, python, icu и, невзирая на кросплатформенность, значительно славнее ставится под *nix системами.
Само же построение сводится к тривиальным:

mkdir build  
cd build 
cmake ..  
make
make install

Задач появиться не должно, все строится в механическом режиме, и ни разу еще меня не огорчало.

Забегая вперед хотелось бы сказать что для удобной работы желанно что бы среда разработки умела исполнять пользовательские шаги построения, а так же имела удобноредактируемый «синтаксический анализатор», мной применяется QtCreator.
Все последующие шаги я буду описывать применительно к вышеобозначенной среде, так как построение с применением командной строки отлично рассмотрено на сайте самой библиотеки. Так же хочу подметить что некоторые действия сборки будут автоматизированы bash скриптами( правда было бы довольно прописания «пользовательского шага» на этапе сборки )

Перед началом работы желанно добавить подсветку синтаксиса для QtCreator, что бы он распознавал специальные файлы *.tmpl, которые применяются в качестве образцов. Данный файл tmpl.xml ( слегка модифицированная подсветка HTML ) должен лежать в папке конфигов «qtcreator/generic-highlighter/tmpl.xml»:

Полный текст файла

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
[
	<!ENTITY name    "[A-Za-z_:][w.:_-]*">
	<!ENTITY entref  "&(#[0-9] |#[xX][0-9A-Fa-f] |&name;);">
]>
<language name="TMPL" version="1" kateversion="2.4" section="Markup" extensions="*.tmpl" mimetype="text/tmpl"  author="Wilbert Berendsen ( original HTML author)(wilbert@kde.nl)" license="LGPL" priority="10">

<highlighting>
<contexts>
  <context name="Start" attribute="Normal Text" lineEndContext="#stay">
    <IncludeRules context="FindHTML" />
  </context>

  <context name="FindHTML" attribute="Normal Text" lineEndContext="#stay">
    <DetectSpaces/>
    <DetectIdentifier/>
    <StringDetect attribute="Comment" context="Comment" String="<!--" beginRegion="comment" />
    <StringDetect attribute="Commenttmpl" context="Commenttmpl" String="<%" beginRegion="commenttmpl" />
    <StringDetect attribute="CDATA" context="CDATA" String="<![CDATA[" beginRegion="cdata" />
    <RegExpr attribute="Doctype" context="Doctype" String="<!DOCTYPEs " beginRegion="doctype" />
    <RegExpr attribute="Processing Instruction" context="PI" String="<?[w:-]*" beginRegion="pi" />
    <RegExpr attribute="Element" context="CSS" String="<styleb" insensitive="TRUE" beginRegion="style" />
    <RegExpr attribute="Element" context="JS" String="<scriptb" insensitive="TRUE" beginRegion="script" />
    <RegExpr attribute="Element" context="El Open" String="<preb" insensitive="TRUE" beginRegion="pre" />
    <RegExpr attribute="Element" context="El Open" String="<divb" insensitive="TRUE" beginRegion="div" />
    <RegExpr attribute="Element" context="El Open" String="<tableb" insensitive="TRUE" beginRegion="table" />
    <RegExpr attribute="Element" context="El Open" String="<ulb" insensitive="TRUE" beginRegion="ul" />
    <RegExpr attribute="Element" context="El Open" String="<olb" insensitive="TRUE" beginRegion="ol" />
    <RegExpr attribute="Element" context="El Open" String="<dlb" insensitive="TRUE" beginRegion="dl" />
    <RegExpr attribute="Element" context="El Open" String="<&name;" />
    <RegExpr attribute="Element" context="El Close" String="</preb" insensitive="TRUE" endRegion="pre" />
    <RegExpr attribute="Element" context="El Close" String="</divb" insensitive="TRUE" endRegion="div" />
    <RegExpr attribute="Element" context="El Close" String="</tableb" insensitive="TRUE" endRegion="table" />
    <RegExpr attribute="Element" context="El Close" String="</ulb" insensitive="TRUE" endRegion="ul" />
    <RegExpr attribute="Element" context="El Close" String="</olb" insensitive="TRUE" endRegion="ol" />
    <RegExpr attribute="Element" context="El Close" String="</dlb" insensitive="TRUE" endRegion="dl" />
    <RegExpr attribute="Element" context="El Close" String="</&name;" />
    <!-- as long as kde gives DTDs the text/html mimetype--><IncludeRules context="FindDTDRules" />
    <IncludeRules context="FindEntityRefs" />
  </context>

  <context name="FindEntityRefs" attribute="Other Text" lineEndContext="#stay">
    <StringDetect attribute="Commenttmpl" context="Commenttmpl" String="<%" beginRegion="commenttmpl" />
    <RegExpr attribute="EntityRef" context="#stay" String="&entref;" />
    <AnyChar attribute="Error" context="#stay" String="&<" />
  </context>

  <context name="FindPEntityRefs" attribute="Other Text" lineEndContext="#stay">
    <RegExpr attribute="EntityRef" context="#stay" String="&entref;" />
    <RegExpr attribute="PEntityRef" context="#stay" String="%&name;;" />
    <AnyChar attribute="Error" context="#stay" String="&%" />
  </context>

  <context name="FindAttributes" attribute="Other Text" lineEndContext="#stay">
    <RegExpr attribute="Attribute" context="#stay" String="&name;" column="0"/>
    <RegExpr attribute="Attribute" context="#stay" String="s &name;" />
    <DetectChar attribute="Attribute" context="Value" char="=" />
  </context>

  <context name="FindDTDRules" attribute="Other Text" lineEndContext="#stay">
    <RegExpr attribute="Doctype" context="Doctype Markupdecl" String="<!(ELEMENT|ENTITY|ATTLIST|NOTATION)b" />
  </context>

  <context name="Comment" attribute="Comment" lineEndContext="#stay">
    <DetectSpaces/>
    <IncludeRules context="##Alerts" />
    <DetectIdentifier/>
    <StringDetect attribute="Comment" context="#pop" String="-->" endRegion="comment" />
    <RegExpr attribute="Error" context="#stay" String="-(-(?!->)) " />
  </context>

  <context name="Commenttmpl" attribute="Commenttmpl" lineEndContext="#stay">
    <DetectSpaces/>
    <DetectIdentifier/>
    <StringDetect attribute="Commenttmpl" context="#pop" String="%>" endRegion="commenttmpl" />
  </context>

  <context name="CDATA" attribute="Other Text" lineEndContext="#stay">
    <DetectSpaces/>
    <DetectIdentifier/>
    <StringDetect attribute="CDATA" context="#pop" String="]]>" endRegion="cdata" />
    <StringDetect attribute="EntityRef" context="#stay" String="]]&gt;" />
  </context>

  <context name="PI" attribute="Other Text" lineEndContext="#stay">
    <Detect2Chars attribute="Processing Instruction" context="#pop" char="?" char1=">" endRegion="pi" />
  </context>

  <context name="Doctype" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Doctype" context="#pop" char=">" endRegion="doctype" />
    <DetectChar attribute="Doctype" context="Doctype Internal Subset" char="[" beginRegion="int_subset" />
  </context>

  <context name="Doctype Internal Subset" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Doctype" context="#pop" char="]" endRegion="int_subset" />
    <IncludeRules context="FindDTDRules" />
    <StringDetect attribute="Comment" context="Comment" String="<!--" beginRegion="comment" />
    <RegExpr attribute="Processing Instruction" context="PI" String="<?[w:-]*" beginRegion="pi" />
    <IncludeRules context="FindPEntityRefs" />
  </context>

  <context name="Doctype Markupdecl" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Doctype" context="#pop" char=">" />
    <DetectChar attribute="Value" context="Doctype Markupdecl DQ" char=""" />
    <DetectChar attribute="Value" context="Doctype Markupdecl SQ" char="'" />
  </context>

  <context name="Doctype Markupdecl DQ" attribute="Value" lineEndContext="#stay">
    <DetectChar attribute="Value" context="#pop" char=""" />
    <IncludeRules context="FindPEntityRefs" />
  </context>

  <context name="Doctype Markupdecl SQ" attribute="Value" lineEndContext="#stay">
    <DetectChar attribute="Value" context="#pop" char="'" />
    <IncludeRules context="FindPEntityRefs" />
  </context>

  <context name="El Open" attribute="Other Text" lineEndContext="#stay">
    <Detect2Chars attribute="Element" context="#pop" char="/" char1=">" />
    <DetectChar attribute="Element" context="#pop" char=">" />
    <IncludeRules context="FindAttributes" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="El Close" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Element" context="#pop" char=">" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="El Close 2" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Element" context="#pop#pop#pop" char=">" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="El Close 3" attribute="Other Text" lineEndContext="#stay">
    <DetectChar attribute="Element" context="#pop#pop#pop#pop" char=">" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="CSS" attribute="Other Text" lineEndContext="#stay">
    <Detect2Chars attribute="Element" context="#pop" char="/" char1=">" endRegion="style" />
    <DetectChar attribute="Element" context="CSS content" char=">" />
    <IncludeRules context="FindAttributes" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="CSS content" attribute="Other Text" lineEndContext="#stay">
    <RegExpr attribute="Element" context="El Close 2" String="</styleb" insensitive="TRUE" endRegion="style" />
    <IncludeRules context="##CSS" includeAttrib="true"/>
  </context>

  <context name="JS" attribute="Other Text" lineEndContext="#stay">
    <Detect2Chars attribute="Element" context="#pop" char="/" char1=">" endRegion="script" />
    <DetectChar attribute="Element" context="JS content" char=">" />
    <IncludeRules context="FindAttributes" />
    <RegExpr attribute="Error" context="#stay" String="S" />
  </context>

  <context name="JS content" attribute="Other Text" lineEndContext="#stay">
    <RegExpr attribute="Element" context="El Close 2" String="</scriptb" insensitive="TRUE" endRegion="script" />
    <RegExpr attribute="Comment" context="JS comment close" String="//(?=.*</scriptb)" insensitive="TRUE" />
    <IncludeRules context="##JavaScript" includeAttrib="true"/>
  </context>

  <context name="JS comment close" attribute="Comment" lineEndContext="#pop">
    <RegExpr attribute="Element" context="El Close 3" String="</scriptb" insensitive="TRUE" endRegion="script" />
    <IncludeRules context="##Alerts" />
  </context>

  <context name="Value" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="Value NQ">
    <DetectChar attribute="Value" context="Value DQ" char=""" />
    <DetectChar attribute="Value" context="Value SQ" char="'" />
    <DetectSpaces />
  </context>

  <context name="Value NQ" attribute="Other Text" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop">
    <IncludeRules context="FindEntityRefs" />
    <RegExpr attribute="Value" context="#stay" String="/(?!>)" />
    <RegExpr attribute="Value" context="#stay" String="[^/><"'s]" />
  </context>

  <context name="Value DQ" attribute="Value" lineEndContext="#stay">
    <DetectChar attribute="Value" context="#pop#pop" char=""" />
    <IncludeRules context="FindEntityRefs" />
  </context>

  <context name="Value SQ" attribute="Value" lineEndContext="#stay">
    <DetectChar attribute="Value" context="#pop#pop" char="'" />
    <IncludeRules context="FindEntityRefs" />
  </context>

</contexts>
<itemDatas>
  <itemData name="Normal Text" defStyleNum="dsNormal" />
  <itemData name="Other Text" defStyleNum="dsNormal" spellChecking="false" />
  <itemData name="Comment" defStyleNum="dsComment" />
  <itemData name="Commenttmpl" defStyleNum="dsComment" color="#66f" />
  <itemData name="CDATA" defStyleNum="dsBaseN" bold="1" spellChecking="false" />
  <itemData name="Processing Instruction" defStyleNum="dsKeyword" spellChecking="false" />
  <itemData name="Doctype" defStyleNum="dsDataType" bold="1" spellChecking="false" />
  <itemData name="Element" defStyleNum="dsKeyword" spellChecking="false" />
  <itemData name="Attribute" defStyleNum="dsOthers" spellChecking="false" />
  <itemData name="Value" defStyleNum="dsString" color="#a00" spellChecking="false" />
  <itemData name="EntityRef" defStyleNum="dsDecVal" spellChecking="false" />
  <itemData name="PEntityRef" defStyleNum="dsDecVal" spellChecking="false" />
  <itemData name="Error" defStyleNum="dsError" spellChecking="false" />
</itemDatas>

</highlighting>
<general>
  <comments>
    <comment name="multiLine" start="<!--" end="-->" />
  </comments>
</general>
</language>
Сейчас приступим

В зависимости построения следует добавить:

LIBS  = -L/usr/local/lib/ -lbooster -lcppcms
INCLUDEPATH  = /usr/local/include
DEPENDPATH  = /usr/local/include

Создаем файл main.cpp и наполняем его дальнейшим содержимым:

#include <cppcms/applications_pool.h>
#include <cppcms/url_dispatcher.h>
#include <cppcms/http_response.h>
#include <cppcms/application.h>
#include <cppcms/url_mapper.h>
#include <cppcms/service.h>

//-------------------------------------------------------------------------------------
// Dsc: Наш класс отрисовки страниц, при запросе некоторого адреса пользователем
//      В первую очередь он попадет сюда
//-------------------------------------------------------------------------------------
class WebSite : public cppcms::application{
public:
  //-------------------------------------------------------------------------------------
  // Dsc: Конструктор, тот, что будет запушен во время старта программы
  //-------------------------------------------------------------------------------------
  WebSite(cppcms::service &s) : cppcms::application(s)
  {}
  //-------------------------------------------------------------------------------------
  // Dsc: Функция в которую мы попадем, если другого не указано в конструкторе
  //      ( об этом позднее )
  //-------------------------------------------------------------------------------------
  virtual void main(std::string path)
  {
    response().out() << "Hello!";
  }
};

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
int main(int argc,char **argv)
{
 try {
    // создаем сервис
    cppcms::service srv(argc,argv);
    // задаем корень
    srv.applications_pool().mount(cppcms::applications_factory<WebSite>());
    // запускаем
    srv.run();
  }
  catch(std::exception const &e) {
    std::cerr << "Failed: " << e.what() << std::endl;
    std::cerr << booster::trace(e) << std::endl;
    return 1;
  }
  return 0;
}

Если вы теснее попытались это запустить, то скорее каждого ничего не получилось, так как дdmk!lt;%= menuItem.first %>”><%= menuItem.second %></a></li> <% end %> </ul> <% end %> </div> </header> <div> <div> <main><% include page_main() %></main> </div> <aside> <div> <% include page_left_sidebar() %> </div> </aside> </div> </div> <footer><% include page_footer() %></footer> </body> </html> <% end template %> <% end view %> <% end skin %>
Что же здесь понаписано?
В самой первой строчке <% c #include "data/tmpl_master.h" %> мы пишем заголовочный файл, в котором будут объявлены наши конструкции данных.
Строка <% skin defskin %> определяет наименование нынешнего скина, то есть у вас могут быть различные отображения для страниц сайта.
Строка <% view Master uses Data::Master %> определяет наименование нынешнего образца как «Master» ( В последствии мы будем его указывать для механизма наполнения страниц ), а так же создает конструкцию Data::Master внутри класса-обертки. Что в переводе на с будет выглядеть как «Data::Master context;»( если вас волнуют подробности — то неизменно дозволено посмотреть сгенерированный фал )
Строки <% template page_main() %>MAIN TEMPLATE<% end %> <% template page_footer() %>Все права защищены<% end %> <% template page_left_sidebar() %>Левая панелька<% end %>
определяют дефолтные значения, которые будут выведены пользователю в случае если мы их не переопределим( то есть являются

virtual const char* page_main(){ return "MAIN TEMPLATE"; }

, так вероятно внятнее. ).
Давайте испробуем собрать. Ясное дело что компилятор с не проглотит файл tmpl. Следственно на поддержка должна прийти утилита, собравшаяся совместно с библиотекой, которая переработает образец до надобного состояния.
Для этого сделаем внутри плана файл «make_templates.sh», вовнутрь которого разместим надобные нам операции( Данный файл легко дозволено заменить либо ручным вызовом данной утилиты либо прописанием ее в «исполняемую часть» вашей среды ):

#!/bin/bash

INPUT=""
OUTPUT=""

while getopts ":i:o:" opt; do
  case $opt in
    i)
      INPUT=$OPTARG
      ;;
    o)
      OUTPUT=$OPTARG
      ;;
    ?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :) 
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

# копируем файлик конфигурации в папку билда
cp $INPUT/config.json $OUTPUT

# сюда пишем все образцы
TEMPLATES="$INPUT/templates/master.tmpl"

# прожевываем образцы в срр-шник
cppcms_tmpl_cc $TEMPLATES -o $INPUT/all_tmpl.cpp

# собираем образцы в библиотеку
g   -shared -fPIC $INPUT/all_tmpl.cpp -o $OUTPUT/libcpp_defskin.so -lcppcms -lbooster

Сейчас в настройках плана QtCreator нужно добавить «пользовательский шаг»
Команда: “./make_templates.sh”
Рабочая директория: “%{sourceDir}”
Доводы команды: “-i %{sourceDir} -o %{buildDir}”
Не позабудьте добавить файлу «исполняемость».

Если сборка прошла успешно, то в директории построения появится помимо прочего библиотека libcpp_defskin.so.
Значимо подметить что собрать библиотеку дозволено статически либо динамически. У меня сделано вторым методом, весьма вам не советую применять 1-й, так как файлы TMPL доводится менять частенько, а перекомпилировать из-за этого каждый план — крайне неблагодарное занятие.

Так же что бы образцы были привязаны к плану — нужно дополнить файл config.json

{	
   "WebSite" : {
      "root" : "",
      "host" : "localhost:8080",
      "locdomain" : "localhost",
   },
   "service" : {
      "ip"  : "0.0.0.0",
      "api" : "http",
      "port" : 8080
   },
   "http" : {
      "script" : "/mb.fcgi" ,
      "rewrite" : [
         { "regex" : "/media(/. )", "pattern" : "$1" },
         { "regex" : ".*" , "pattern" : "/mb.fcgi$0" }
      ],
   },
   "views" : {
      "default_skin" : "defskin" ,
      "paths" : [ "./" ],
      "skins" : [ "cpp_defskin" ],
   },
}

И внести соответствующие метаморфозы в main.cpp:

#include "data/tmpl_master.h"
...
WebSite::main(std::string path)
{
    Data::Master tmpl;
    tmpl.page.title = path;
    tmpl.page.description = "description";
    tmpl.page.keywords = "keywords";
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/","MAIN"));
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/else","ELSE"));
    render("Master",tmpl);
}

Сейчас при запуске плана мы обязаны увидеть итог образца. Но постойте, вовсе позабыл про css и изображения, теперь исправлюсь.
Добавляем в config.json еще один пункт

   "file_server" : {
      "enable" : true,
      "listing" : true,
      "document_root" : "./media"
   },

Тут определенно необходимо пояснить, что данным пунктом мы разрешаем бинарнику глядеть в файловую систему. А правила по которым он это делает описаны в сегменты http{ "regex" : "/media(/. )", "pattern" : "$1" },
то есть всякий запрос, начинающийся с /media/ следует перенаправлять «файловому серверу».
Сотворим в папке плана папку media, а так же добавим соответствующий пункт в make_templates.sh:

# копируем медиа данные в папку билда
cp -R $INPUT/media $OUTPUT

Внутри папки media ( в директории исходников плана ) сделаем подпапку css, а в ней файл style.css

Спрятанный текст

/* Eric Meyer's CSS Reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
/* End of Eric Meyer's CSS Reset */

html {
	height: 100%;
}
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary {
	display: block;
}
body {
	font: 12px/18px Arial, sans-serif;
	width: 100%;
	height: 100%;
}
.wrapper {
	width: 800px;
	margin: 0 auto;
	min-height: 100%;
	height: auto !important;
	height: 100%;
}

/* Header
-----------------------------------------------------------------------------*/
.header {
	height: 50px;
	background: #FFE680;
}

/* Middle
-----------------------------------------------------------------------------*/
.middle {
	width: 100%;
	padding: 0 0 50px;
	position: relative;
}
.middle:after {
	display: table;
	clear: both;
	content: '';
}
.container {
	width: 100%;
	float: left;
	overflow: hidden;
}
.content {
	padding: 0 270px 0 270px;
}

/* Left Sidebar
-----------------------------------------------------------------------------*/
.left-sidebar {
	float: left;
	width: 250px;
	margin-left: -100%;
	position: relative;
	background: #B5E3FF;
}

/* Footer
-----------------------------------------------------------------------------*/
.footer {
	width: 800px;
	margin: -50px auto 0;
	height: 50px;
	background: #BFF08E;
	position: relative;
}

Пробуем собрать еще раз.
Сейчас, когда сайт схож на первую работу начинающего мастера — дозволено перейти к самому основному.

Наследование образцов

Механизм наследования образцов предельно примитивен. Определяем от какого образца наследуемся и дописываем переопределение функции итога контента.
Сотворим файл файл tmpl_news.h в папке data

#ifndef TMPL_NEWS_H
#define TMPL_NEWS_H
#include "tmpl_master.h"

namespace Data {
  //-------------------------------------------------------------------------------------
  // Dsc: Новостной контент
  //-------------------------------------------------------------------------------------
  struct News :public Master{
    //-------------------------------------------------------------------------------------
    // Dsc: Основная новость
    //-------------------------------------------------------------------------------------
    std::string mainNews;
    //-------------------------------------------------------------------------------------
    // Dsc: Конструктор страницы
    //-------------------------------------------------------------------------------------
    News() :
      Master()
    {}
    //-------------------------------------------------------------------------------------
    // Dsc: Ленивый деструктор
    //-------------------------------------------------------------------------------------
    ~News(){}
  };
}

#endif // TMPL_NEWS_H

Так же добавим файл news.tmpl в папку templates

<% c   #include "data/tmpl_news.h" %>
<% skin defskin %>
<% view News uses Data::News extends Master %>
<% template page_main() %><%= mainNews %><% end %>
<% end view %>
<% end skin %>

Добавим путь до файлика в скрипт сборки ( должно выглядеть как-то так):

TEMPLATES="$INPUT/templates/master.tmpl"
TEMPLATES="$TEMPLATES $INPUT/templates/news.tmpl"

Изменяем файл main.cpp

#include <cppcms/applications_pool.h>
#include <cppcms/url_dispatcher.h>
#include <cppcms/http_response.h>
#include <cppcms/application.h>
#include <cppcms/url_mapper.h>
#include <cppcms/service.h>

#include "data/tmpl_master.h"
#include "data/tmpl_news.h"

//-------------------------------------------------------------------------------------
// Dsc: Наш класс отрисовки страниц, при запросе некоторого адреса пользователем
//      В первую очередь он попадет сюда
//-------------------------------------------------------------------------------------
class WebSite : public cppcms::application{
public:
  //-------------------------------------------------------------------------------------
  // Dsc: Конструктор, тот, что будет запушен во время старта программы
  //-------------------------------------------------------------------------------------
  WebSite(cppcms::service &s) : cppcms::application(s)
  {
    dispatcher().assign("/news(.*)",&WebSite::news,this,1);
    mapper().assign("news","/news");

    dispatcher().assign("(/?)",&WebSite::master,this,1);
    mapper().assign("master","/");
  }
  //-------------------------------------------------------------------------------------
  // Dsc: Функция в которую мы попадем, если другого не указано в конструкторе
  //      ( об этом позднее )
  //-------------------------------------------------------------------------------------
  virtual void main(std::string path)
  {
    cppcms::application::main(path);
  }
  //-------------------------------------------------------------------------------------
  // Dsc: Рендеринг базового контента
  //-------------------------------------------------------------------------------------
  virtual void master(std::string path)
  {
    Data::Master tmpl;
    tmpl.page.title = path;
    tmpl.page.description = "description";
    tmpl.page.keywords = "keywords";
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/","MASTER"));
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/news","NEWS"));
    render("Master",tmpl);
  }
  //-------------------------------------------------------------------------------------
  // Dsc: Рендеринг новостей
  //-------------------------------------------------------------------------------------
  virtual void news(std::string path)
  {
    Data::News tmpl;
    tmpl.page.title = path;
    tmpl.page.description = "description";
    tmpl.page.keywords = "keywords";
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/","MASTER"));
    tmpl.page.menuList.insert(std::pair<std::string,std::string>("/news","NEWS"));
    tmpl.mainNews = "Сенсация! У нас на сайте ничего не случилось!";
    render("News",tmpl);
  }
};

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
int main(int argc,char **argv)
{
  try {
    // создаем сервис
    cppcms::service srv(argc,argv);
    // задаем корень
    srv.applications_pool().mount(cppcms::applications_factory<WebSite>());
    // запускаем
    srv.run();
  }
  catch(std::exception const &e) {
    std::cerr << "Failed: " << e.what() << std::endl;
    std::cerr << booster::trace(e) << std::endl;
    return 1;
  }
  return 0;
}

}

Основные метаморфозы в файле случились в конструкторе, где мы указали какая функция за итог какой страницы отвечает.
Сейчас эти страницы выводят разные образцы.
Особенно значимый момент — порядок подачи списка файлов шаблонизатору ( файлы-потомки обязаны следовать позже родителей, ин

 

Источник: programmingmaster.ru

 

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB