今日、 CppCMS (C ++のテンプレートライブラリ)でWebサイトを作成した私の個人的な経験を共有したいと思います。 「初心者のCppCMSプログラマを支援する」と呼ぶことができます。
C ++でサイトを書く理由
このような決定に対する賛否両論は非常に多様である可能性があり、「語学学校」の戦争を引き起こさないように、自動車との類似性を引きます。 私はそれが好きです。 行く 売りたくない!」
追加の議論のうち、この言語は私の職場のプロファイルであるということです。
何か書きましょう
しかし、前に
サイトを作成する前に、まず作業中のマシンにサイト(CppCMS)をインストールする必要があります。 ライブラリは、その作業のためにBoost c ++、pcre、crypt、python、icuを最も堂々と必要とし、クロスプラットフォームであるにもかかわらず、* nixシステムの下にインストールする方がはるかに優れています。
構造自体は平凡になります:
mkdir build cd build cmake .. make make install
問題が発生することはありません、すべてが自動モードで構築されており、私は怒ったことはありません。
今後は、快適な作業のために、開発環境がカスタム構築手順を実行でき、便利に編集された「パーサー」を持つことが望ましいと言いたいと思います。私はQtCreatorを使用します。
コマンドラインを使用したビルドはライブラリ自体のサイトで十分に検討されているため、上記の環境に関連するすべての追加手順を説明します。 また、一部のアセンブリアクションはbashスクリプトによって自動化されることに注意してください(ただし、アセンブリ段階で「ユーザーステップ」を規定するだけで十分です)
作業を開始する前に、テンプレートとして使用される特別な* .tmplファイルを認識するように、QtCreatorの構文強調表示を追加することをお勧めします。 このtmpl.xmlファイル(わずかに変更されたHTML強調表示)は、qtcreator / generic-highlighter / tmpl.xml configフォルダーにあります。
ファイルの全文
<?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="<!DOCTYPE\s+" beginRegion="doctype" /> <RegExpr attribute="Processing Instruction" context="PI" String="<\?[\w:-]*" beginRegion="pi" /> <RegExpr attribute="Element" context="CSS" String="<style\b" insensitive="TRUE" beginRegion="style" /> <RegExpr attribute="Element" context="JS" String="<script\b" insensitive="TRUE" beginRegion="script" /> <RegExpr attribute="Element" context="El Open" String="<pre\b" insensitive="TRUE" beginRegion="pre" /> <RegExpr attribute="Element" context="El Open" String="<div\b" insensitive="TRUE" beginRegion="div" /> <RegExpr attribute="Element" context="El Open" String="<table\b" insensitive="TRUE" beginRegion="table" /> <RegExpr attribute="Element" context="El Open" String="<ul\b" insensitive="TRUE" beginRegion="ul" /> <RegExpr attribute="Element" context="El Open" String="<ol\b" insensitive="TRUE" beginRegion="ol" /> <RegExpr attribute="Element" context="El Open" String="<dl\b" insensitive="TRUE" beginRegion="dl" /> <RegExpr attribute="Element" context="El Open" String="<&name;" /> <RegExpr attribute="Element" context="El Close" String="</pre\b" insensitive="TRUE" endRegion="pre" /> <RegExpr attribute="Element" context="El Close" String="</div\b" insensitive="TRUE" endRegion="div" /> <RegExpr attribute="Element" context="El Close" String="</table\b" insensitive="TRUE" endRegion="table" /> <RegExpr attribute="Element" context="El Close" String="</ul\b" insensitive="TRUE" endRegion="ul" /> <RegExpr attribute="Element" context="El Close" String="</ol\b" insensitive="TRUE" endRegion="ol" /> <RegExpr attribute="Element" context="El Close" String="</dl\b" 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="]]>" /> </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="</style\b" 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="</script\b" insensitive="TRUE" endRegion="script" /> <RegExpr attribute="Comment" context="JS comment close" String="//(?=.*</script\b)" 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="</script\b" 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; }
すでにこれを実行しようとした場合、おそらく何も起きていない可能性があります。完全な作業のために、サーバー用の十分な構成ファイルがないため、その場所を起動時にバイナリに渡す必要があります
WebApp.bin -c 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" : ".*" , "pattern" : "/mb.fcgi$0" } ], } }
それで十分でしょう。
また、「プログラミング環境設定」で起動パラメータを登録するのに適したオプションです
したがって、追加して実行し、開きます。
印象的? いや?
この例では、テンプレートエンジンを使用しなかったが、平凡なライン出力に制限されているため、これは事実です。 ただし、この例では、すべてが機能することを確認できます。
パターンを使用する
ライブラリテンプレートエンジンによって* .cppファイルに「変換」される最初のテンプレートを書きましょう。
そのため、まず、動的データ(テンプレートデータ)の構造を含むヘッダーファイルを追加します。 デフォルトでは、プロジェクト内のデータフォルダーに配置されます。
data / tmpl_master.h
#ifndef TMPL_MASTER_H #define TMPL_MASTER_H #include <cppcms/view.h> namespace Data { //------------------------------------------------------------------------------------- // Dsc: //------------------------------------------------------------------------------------- struct infoPage { std::string title; // std::string description; // std::string keywords; // std::map<std::string,std::string> menuList; // (url,desc) //------------------------------------------------------------------------------------- // Dsc: , //------------------------------------------------------------------------------------- infoPage() : title (""), description(""), keywords (""), menuList ( ) {} //------------------------------------------------------------------------------------- // Dsc: , //------------------------------------------------------------------------------------- ~infoPage(){} }; //------------------------------------------------------------------------------------- // Dsc: //------------------------------------------------------------------------------------- struct Master :public cppcms::base_content { infoPage page; //------------------------------------------------------------------------------------- // Dsc: //------------------------------------------------------------------------------------- Master() : page() {} //------------------------------------------------------------------------------------- // Dsc: //------------------------------------------------------------------------------------- ~Master(){} }; } #endif
通常、このファイルの内容は、スマートコードによって区別されません。実際、テンプレートで使用される変数を記述するための単なるコンテナです。
テンプレート自体の作成を開始し、テンプレートフォルダーを作成し、その中に次の内容のmaster.tmplファイルを作成します。
<% c++ #include "data/tmpl_master.h" %> <% skin defskin %> <% view Master uses Data::Master %> <% template page_main() %>MAIN TEMPLATE<% end %> <% template page_footer() %> <% end %> <% template page_left_sidebar() %> <% end %> <% template render() %> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title><%= page.title %></title> <meta name="keywords" content="<%= page.keywords %>" /> <meta name="description" content="<%= page.description %>" /> <link href="/media/css/style.css" rel="stylesheet"> </head> <body> <div class="wrapper"> <header class="header"> <div class="nav" > <% foreach menuItem in page.menuList %> <ul> <% item %> <li><a href="<%= menuItem.first %>"><%= menuItem.second %></a></li> <% end %> </ul> <% end %> </div> </header> <div class="middle"> <div class="container"> <main class="content"><% include page_main() %></main> </div> <aside class="left-sidebar"> <div> <% include page_left_sidebar() %> </div> </aside> </div> </div> <footer class="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構造も作成します。 C ++翻訳では、「Data :: Master context;」のようになります(詳細に興味がある場合は、生成されたファイルを常に確認できます)
行
<% template page_main() %>MAIN TEMPLATE<% end %>
<% template page_footer() %> <% end %>
<% template page_left_sidebar() %> <% end %>
<% template page_main() %>MAIN TEMPLATE<% end %>
<% template page_footer() %> <% end %>
<% template page_left_sidebar() %> <% end %>
再定義しない場合にユーザーに表示されるデフォルト値を決定します(つまり、
virtual const char* page_main(){ return "MAIN TEMPLATE"; }
、おそらくより理解しやすい。 )
組み立ててみましょう。 C ++コンパイラが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}」
「executable」ファイルを追加することを忘れないでください。
アセンブリが成功した場合、libcpp_defskin.soライブラリがビルドディレクトリに表示されます。
ライブラリを静的または動的に構築できることに注意することが重要です。 私は2番目の方法を実行しました。TMPLファイルを頻繁に変更する必要があるため、1番目の方法を使用しないことを強くお勧めします。
また、テンプレートがプロジェクトに関連付けられるように、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 /で始まるリクエストはすべて「ファイルサーバー」にリダイレクトされます。
プロジェクトフォルダーにメディアフォルダーを作成し、対応するアイテムをmake_templates.shに追加します。
# cp -R $INPUT/media $OUTPUT
メディアフォルダー内(プロジェクトソースディレクトリ内)に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ファイルを作成します。
#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ファイルをテンプレートフォルダーに追加します。
<% 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; } }
ファイルの主な変更はコンストラクターで行われ、どの関数がどのページの出力を担当するかを示しました。
現在、これらのページにはさまざまなテンプレートが表示されています。
特に重要な点は、ファイルのリストをテンプレートエンジンに送信する手順です(親の後に子ファイルが続く必要があります。そうしないと、エラーがスローされます)。
これについては、最初の部分を終了する予定です。