Browse Source

Now templates should work ;)

master
Artyom Beilis 14 years ago
parent
commit
1945430cef
19 changed files with 821 additions and 676 deletions
  1. +35
    -3
      CMakeLists.txt
  2. +9
    -3
      TODO
  3. +22
    -0
      application.cpp
  4. +6
    -0
      application.h
  5. +1
    -0
      base_view.h
  6. +4
    -3
      config.js
  7. +621
    -611
      cppcms_tmpl_cc
  8. +11
    -1
      hello_world.cpp
  9. +1
    -1
      hello_world_skin1.tmpl
  10. +36
    -42
      hello_world_view.h
  11. +5
    -4
      hello_world_view1.tmpl
  12. +13
    -0
      http_context.cpp
  13. +3
    -0
      http_context.h
  14. +7
    -0
      service.cpp
  15. +2
    -0
      service.h
  16. +1
    -0
      service_impl.h
  17. +8
    -0
      view.h
  18. +27
    -6
      views_pool.cpp
  19. +9
    -2
      views_pool.h

+ 35
- 3
CMakeLists.txt View File

@@ -75,6 +75,7 @@ if(NOT DISABLE_ICONV)
endif(NOT DISABLE_ICONV)

include_directories(${CMAKE_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR})
include_directories(boost_locale)

set(CPPCMS_LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
@@ -91,7 +92,7 @@ check_cxx_source_compiles(
int main() { std::u16string s16; std::u32string s32; }"
HAVE_CPP0X_UXSTRING)

Check_cxx_source_compiles(
check_cxx_source_compiles(
"#include <list>
int main(){std::list<int> l; auto p=l.begin();}"
HAVE_CPP_0X_AUTO)
@@ -257,8 +258,39 @@ if(NOT DISABLE_SHARED)
target_link_libraries(cppcms boost_locale)
endif(NOT DISABLE_SHARED)


add_executable(hello_world hello_world.cpp)
find_program(PYTHON python)
if(NOT PYTHON)
message(FATAL "Can't build without Python interpreter")
endif(NOT PYTHON)


# Templates builds

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/skin1.cpp
COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/cppcms_tmpl_cc
-n skin1
-o ${CMAKE_CURRENT_BINARY_DIR}/skin1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_skin1.tmpl
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_view1.tmpl
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/cppcms_tmpl_cc
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_skin1.tmpl
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_view1.tmpl)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/skin2.cpp
COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/cppcms_tmpl_cc
-n skin2
-o ${CMAKE_CURRENT_BINARY_DIR}/skin2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_skin2.tmpl
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_view1.tmpl
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/cppcms_tmpl_cc
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_skin2.tmpl
${CMAKE_CURRENT_SOURCE_DIR}/hello_world_view1.tmpl)

add_executable(hello_world hello_world.cpp skin1.cpp skin2.cpp)
target_link_libraries(hello_world ${CPPCMS_LIB})

add_executable(cppcms_config_find_param cppcms_config_find_param.cpp json.cpp)


+ 9
- 3
TODO View File

@@ -1,3 +1,9 @@
- Implement full util::format
- Add macros for variadic templates support
- Implement to_(w)string
- form.*
Implement, Select, Radio, Date-Time
- http_request.*, cgi_api.*
Implement File Upload
- Implement Asynchronous API
- Implement JSON-RPC
- Reintegrate Sessions Support
- Reintegrate Cache Support
- Update cppcms_tmpl_cc according to new code

+ 22
- 0
application.cpp View File

@@ -8,6 +8,7 @@
#include "intrusive_ptr.h"
#include "applications_pool.h"
#include "http_response.h"
#include "views_pool.h"

#include <set>
#include <vector>
@@ -158,6 +159,27 @@ void application::assign(application *app,std::string regex,int part)
add(*app,regex,part);
}

void application::render(std::string template_name,base_content &content)
{
service().views_pool().render(context().skin(),template_name,response().out(),content);
}

void application::render(std::string skin,std::string template_name,base_content &content)
{
service().views_pool().render(skin,template_name,response().out(),content);
}

void application::render(std::string template_name,std::ostream &out,base_content &content)
{
service().views_pool().render(context().skin(),template_name,out,content);
}

void application::render(std::string skin,std::string template_name,std::ostream &out,base_content &content)
{
service().views_pool().render(skin,template_name,out,content);
}


void application::recycle()
{
if(root()->d->conn) {


+ 6
- 0
application.h View File

@@ -14,6 +14,7 @@ namespace cppcms {
class url_dispatcher;
class applications_pool;
class application;
class base_content;

namespace locale {
class environment;
@@ -42,6 +43,11 @@ namespace cppcms {
http::response &response();
url_dispatcher &dispatcher();

void render(std::string template_name,base_content &content);
void render(std::string skin,std::string template_name,base_content &content);
void render(std::string template_name,std::ostream &out,base_content &content);
void render(std::string skin,std::string template_name,std::ostream &out,base_content &content);

void add(application &app);
void add(application &app,std::string regex,int part);



+ 1
- 0
base_view.h View File

@@ -13,6 +13,7 @@
#include "hold_ptr.h"
#include "base_content.h"
#include "noncopyable.h"
#include "config.h"

namespace cppcms {



+ 4
- 3
config.js View File

@@ -47,9 +47,10 @@
"cookies_secure" : false
},
"views" : {
"paths" : [ "./teplates" ],
"skins" : [ "skin1", "skin2" ],
"auto_reload" : true
"default_skin" : "skin1"
// "paths" : [ "./teplates" ],
// "skins" : [ "skin1", "skin2" ],
// "auto_reload" : true
},
"file_server" : {
"enable" : true,


+ 621
- 611
cppcms_tmpl_cc
File diff suppressed because it is too large
View File


+ 11
- 1
hello_world.cpp View File

@@ -18,6 +18,8 @@
#include <boost/bind.hpp>
#include <fstream>

#include "hello_world_view.h"


class chat : public cppcms::application {
public:
@@ -189,13 +191,13 @@ public:
};



class hello : public cppcms::application {
public:
hello(cppcms::service &srv) :
cppcms::application(srv)
{
dispatcher().assign("^/(\\d+)$",&hello::num,this,1);
dispatcher().assign("^/view(/(\\w+))?$",&hello::view_test,this,2);
dispatcher().assign("^/get$",&hello::gform,this);
dispatcher().assign("^/post$",&hello::pform,this);
dispatcher().assign("^/err$",&hello::err,this);
@@ -207,6 +209,14 @@ public:
{
}

void view_test(std::string skin)
{
view::hello c;
if(!skin.empty())
context().skin(skin);
render("hello",c);
}

void devide(cppcms::locale::boundary::boundary_type type,std::string const &str,char const *name)
{
response().out()<<name<<":";


+ 1
- 1
hello_world_skin1.tmpl View File

@@ -1,7 +1,7 @@
<% c++ #include "hello_world_view.h" %>
<% namespace vary %>
<% class master uses view::master %>
<% template test(string &v,int p) %>
<% template test(std::string &v,int p) %>
<% foreach c in v %>
<% item %><% c %><% end %>
<% end %>


+ 36
- 42
hello_world_view.h View File

@@ -1,8 +1,5 @@
#include "base_view.h"
#include "application.h"
#include "view.h"
#include <list>
#include "form.h"
using namespace cppcms;
class my_hello_world;
namespace view {

@@ -17,60 +14,57 @@ struct data {
data(char const *n="",int v=0) : name(n),val(v){}
};

struct my_form : public form {
widgets::text username;
widgets::textarea name;
widgets::email mail;
widgets::password p1;
widgets::password p2;
widgets::number<int> integer;
widgets::number<double> real;
widgets::checkbox ok;
widgets::select fruit;
struct a_form : public cppcms::form {
cppcms::widgets::text username;
cppcms::widgets::textarea name;
cppcms::widgets::email mail;
cppcms::widgets::password p1;
cppcms::widgets::password p2;
cppcms::widgets::numeric<int> integer;
cppcms::widgets::numeric<double> real;
cppcms::widgets::checkbox ok;
//widgets::select fruit;
//widgets::radio fruit;
widgets::select_multiple meat;
widgetset my_set;
my_form(application *w) :
username("user",w->gettext("Username")),
name("name",w->gettext("Real Name")),
mail("mail",w->gettext("Mail")),
p1("pass",w->gettext("Password")),
p2("passcopy",w->gettext("Confirm")),
integer("int",w->gettext("Integer")),
real("real",w->gettext("Real")),
ok("ok",w->gettext("Never save")),
fruit("fr",w->gettext("Fruit")),
meat("mt",2,w->gettext("Meat"))
//widgets::select_multiple meat;
//widgetset my_set;
a_form()
{
*this & username & mail & name & p1 & p2 &
integer & real & ok & fruit & meat ;
my_set<< username<<mail<<name<<p1<<p2<<integer<<real<<ok<<fruit<<meat;
username.set_nonempty();
name.set_nonempty();
p2.set_equal(p1);
p2.help=w->gettext("(Same as above)");
p1.set_nonempty();
p2.set_nonempty();
real.set_range(-1.0,1.5);
fruit.add("Orange");
using cppcms::locale::translate;
username.message(translate("Username"));
name.message(translate("Real Name"));
mail.message(translate("E-Mail"));
p1.message(translate("Password"));
p2.message(translate("Confirm"));
integer.message(translate("Integer"));
real.message(translate("Real"));
ok.message(translate("Never Save"));
*this + username + mail + name + p1 + p2 +
integer + real + ok;
username.non_empty();
name.non_empty();
p2.check_equal(p1);
p2.help(translate("(Same as above)"));
p1.non_empty();
p2.non_empty();
real.range(-1.0,1.5);
/* fruit.add("Orange");
fruit.add("Palm");
meat.add("Beef");
meat.add("<<Chicken>>");
meat.add("Duck");
meat.set_min(2);
meat.help=w->gettext("At least two choises");
meat.help=w->gettext("At least two choises");*/
}
};


struct hello : public master {
string username,realname,password;
std::string username,realname,password;
bool ok;
std::string msg;
std::list<int> numbers;
std::list<data> lst;
my_form form;
hello(application *w) : form(w) {}
a_form form;
};

};


+ 5
- 4
hello_world_view1.tmpl View File

@@ -10,11 +10,11 @@
</form>
<form action="" method="post">
<p>
<% foreach widget w in form.my_set %>
<% foreach w in form %>
<% separator %><br/><% item %>
<% if not empty w.msg %><% w.msg %>:<% end %>
<% if w.has_message() %><% w.message() %>:<% end %>
<% form input w %>
<% if not w.is_valid %>:<% form error w %><% end %>
<% if not w.valid() %>:<% w.error_message() %><% end %>
<% end %>
<% end %>
<input type="submit" value="Submit" />
@@ -30,10 +30,11 @@
<% foreach x in numbers %>
<ul>
<% item %>
<li><% ngt "passed one day","passed %1% days",x using x %></li>
<li><% ngt "passed one day","passed {1} days",x using x %></li>
<% end %>
</ul>
<% end %>
<% end template %>
<% end class %>
<% end namespace %>


+ 13
- 0
http_context.cpp View File

@@ -9,6 +9,7 @@
#include "applications_pool.h"
#include "thread_pool.h"
#include "url_dispatcher.h"
#include "views_pool.h"
#include "cppcms_error.h"

#include <boost/bind.hpp>
@@ -19,6 +20,7 @@ namespace http {

struct context::data {
std::locale locale;
std::string skin;
http::request request;
std::auto_ptr<http::response> response;
data(context &cntx) :
@@ -33,6 +35,17 @@ context::context(intrusive_ptr<impl::cgi::connection> conn) :
{
d.reset(new data(*this));
d->response.reset(new http::response(*this));
skin(service().views_pool().default_skin());
}

std::string context::skin()
{
return d->skin;
}

void context::skin(std::string const &skin)
{
d->skin=skin;
}




+ 3
- 0
http_context.h View File

@@ -36,6 +36,9 @@ namespace cppcms {
void locale(std::string const &name);
cppcms::service &service();

std::string skin();
void skin(std::string const &name);

void run();

typedef enum {


+ 7
- 0
service.cpp View File

@@ -13,6 +13,7 @@
#include "internal_file_server.h"
#include "json.h"
#include "localization.h"
#include "views_pool.h"


#ifdef CPPCMS_POSIX
@@ -140,6 +141,12 @@ void service::setup()
{
int apps=settings().get("service.applications_pool_size",threads_no()*2);
impl_->applications_pool_.reset(new cppcms::applications_pool(*this,apps));
impl_->views_pool_.reset(new cppcms::views_pool(settings()));
}

cppcms::views_pool &service::views_pool()
{
return *impl_->views_pool_;
}




+ 2
- 0
service.h View File

@@ -17,6 +17,7 @@ namespace cppcms {

class applications_pool;
class thread_pool;
class views_pool;
namespace json {
class value;
}
@@ -34,6 +35,7 @@ namespace cppcms {
cppcms::applications_pool &applications_pool();
cppcms::thread_pool &thread_pool();
json::value const &settings();
cppcms::views_pool &views_pool();

locale::generator const &generator();
std::locale locale();


+ 1
- 0
service_impl.h View File

@@ -35,6 +35,7 @@ namespace impl {
std::auto_ptr<applications_pool> applications_pool_;
std::auto_ptr<thread_pool> thread_pool_;
std::auto_ptr<locale::generator> locale_generator_;
std::auto_ptr<views_pool> views_pool_;
std::locale default_locale_;

#ifdef CPPCMS_WIN32


+ 8
- 0
view.h View File

@@ -0,0 +1,8 @@
#ifndef CPPCMS_VIEW_H
#define CPPCMS_VIEW_H
#include "form.h"
#include "filters.h"
#include "base_view.h"
#include "views_pool.h"
#endif


+ 27
- 6
views_pool.cpp View File

@@ -125,12 +125,12 @@ public:
time_stamp_ = st.st_mtime;

shared_object_.reset(new impl::shared_object(file_name,reloadable));
typedef void (*loader_type)(mapping_type *);
typedef void (*loader_type)(mapping_type &);
loader_type loader=reinterpret_cast<loader_type>(shared_object_->symbol("cppcms_"+name+"_get_skins"));
if(!loader) {
throw cppcms_error(file_name + " is not CppCMS loadable skin");
}
loader(&mapping_);
loader(mapping_);
return;
}
throw cppcms_error("Can't load skin " + name);
@@ -181,26 +181,38 @@ struct views_pool::data {
std::vector<std::string> search_path;
};

views_pool::views_pool()
views_pool::views_pool() :
d(new data())
{
}

views_pool::views_pool(json::value const &settings)
std::string views_pool::default_skin() const
{
return d->default_skin;
}

views_pool::views_pool(json::value const &settings) :
d(new data())
{
d->skins=static_instance().d->skins;
std::vector<std::string> paths=settings.get("views.paths",std::vector<std::string>());
d->search_path=paths;
std::vector<std::string> skins=settings.get("views.skins",std::vector<std::string>());
d->dynamic_reload= settings.get("views.auto_reload",false);
if(paths.empty() || skins.empty())
d->default_skin = settings.get<std::string>("views.default_skin","");
if(d->default_skin.empty() && d->skins.size()==1)
d->default_skin=d->skins.begin()->first;
if(paths.empty() || skins.empty()) {
return;
}
for(unsigned i=0;i<skins.size();i++) {
std::string name=skins[i];
if(d->skins.find(name)!=d->skins.end())
throw cppcms_error("Two skins with same name provided:" + name);
d->skins[name]=skin(name,paths,d->dynamic_reload);
}
d->default_skin = settings.get<std::string>("views.default_skin","");
if(d->default_skin.empty())
d->default_skin=skins[0];
}

void views_pool::render(std::string skin_name,std::string template_name,std::ostream &out,base_content &content)
@@ -241,6 +253,15 @@ views_pool::~views_pool()
{
}

void views_pool::add_view(std::string name,mapping_type const &mapping)
{
data::skins_type::iterator p=d->skins.find(name);
if(p!=d->skins.end())
throw cppcms_error("Skin " + name + "can't be loaded twice");
d->skins[name]=skin(name,mapping);
}


namespace { // Make sure that static views pool is loaded
struct loader {
loader()


+ 9
- 2
views_pool.h View File

@@ -19,7 +19,7 @@ namespace cppcms {
typedef std::map<std::string,view_factory_type> mapping_type;

template<typename View,typename Content>
std::auto_ptr<base_view> view_builder(std::ostream &stream,base_content *c)
static std::auto_ptr<base_view> view_builder(std::ostream &stream,base_content *c)
{
std::auto_ptr<base_view> p(new View(stream,dynamic_cast<Content &>(*c)));
return p;
@@ -29,8 +29,15 @@ namespace cppcms {
views_pool(json::value const &settings);
~views_pool();
void render(std::string template_name,std::ostream &out,base_content &content);
///
/// Thread safe member function
///
void render(std::string skin,std::string template_name,std::ostream &out,base_content &content);

///
/// Get default skin name
///
std::string default_skin() const;
void add_view(std::string skin,mapping_type const &mapping);



Loading…
Cancel
Save