`
qqsunkist
  • 浏览: 33102 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

初识CPPCMS中的template概念

 
阅读更多

问题描述:

cppcms事实上一个mvc的web架构,其中一个重要组成部分就是view-html rendering系统。cppcms的网页是用特殊的template语言编写,编写后的网页可以由翻译器(cppcms_tmpl_cc)翻译成c++代码,最后可以由编译器编译成shared object。

通常情况下,cppcms template系统使用push model, 当用户应用程序准备好内容,将内容推送给web template系统用以渲染。所以mvc对应的角色如下:content -- model, application -- controller, view -- template system. 

上面的这段描述摘自tutorial-2(starting with templates)。如果编写较为复杂的网站,我们需要摸清template系统翻译后的c++代码是如何跟扮演model角色的content的c++代码进行耦合的)

 

问题解决:

 

1. 先根据tutorial-2中的示例代码,编写如下的template。

 

<% c++ #include "content.h" %>
<% skin my_skin %>
<% view message uses content::message %>
<% template render() %>
<html>
<body>
<h1><%= text %> World!</h1>
</body>
<html>
<% end template %>
<% end view %>
<% end skin %>

 

 2. model —— content.h的定义(非常简单,只是包含一个字符串数据的model定义,定义的结构体必须公有继承于base::content类)

 

#ifndef CONTENT_H
#define CONTENT_H

#include <cppcms/view.h>
#include <string>

namespace content  {
    struct message : public cppcms::base_content {
        std::string text;
    };
}

#endif

 

 3. controller —— hello-tmpl.cpp (my_hello_world application, 按照mvc模式,controller里必须关联model与view, 如何关联的呢?)

 

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

#include "content.h"

class my_hello_world : public cppcms::application {
public:
    my_hello_world(cppcms::service &s) :
       cppcms::application(s)
    {
    }
    virtual void main(std::string /*url*/)
    {
        content::message c;  // uses model 'message', which is defined in 'content.h'.
        c.text=">>>Hello<<<";  // initialize member model data
        render("message",c);  // collabrate with model, and view, where view is a template name. 	
    }
};

在my_hello_world的main函数中,调用了render函数,该函数的接口定义如下

void cppcms::application::render(std::string template_name,
base_content &content)

/*		
Render a template template_name of default skin using content content.

Side effect requires: output stream for response class, causes all updated session data be saved and all headers be written. You can't change headers after calling this function.
*/

 根据此api,我们知道了为什么message必须继承于cppcms::base_content的原因,同时知道template的名称是message.然后,我们再看template是如何定义template的名称是message的。很显然,包含message关键字的语句,只有这么一句,即 <%view message uses content::message%>。这条语句实际上有两个语义

1. 定义了template name是message

2. 关联model数据 content::message

 

但是这个语句同样也给出了一些让人费解的关键词,比如view. 既然定义template name, 为什么不直接使用这样的语句<% template message uses content::message %>呢?view与template到底又是什么区别呢?在此语句后面的<% template render() %>句子中,template关键字到底是什么语义呢?其中render(),之前并未给出定义,为什么要加小括号?难道跟my_hello_world()的render() api有关系?skin关键字的语义又是什么?

 

上述的问题通过翻译后的c++代码或许能明朗些。

#include "content.h" 
namespace my_skin {
	struct message :public cppcms::base_view
	{
		content::message &content;
		message(std::ostream &_s,content::message &_content): cppcms::base_view(_s),content(_content)
		{
		}
		virtual void render() {
			out()<<"\n"
				"<html>\n"
				"<body>\n"
				"<h1>";
			out()<<cppcms::filters::escape(content.text);
			out()<<" World! </h1>\n"
				"</body>\n"
				"</html>\n"
				"";
		} // end of template render
	}; // end of class message
} // end of namespace my_skin

namespace {
 cppcms::views::generator my_generator; 
 struct loader { 
  loader() { 
   my_generator.name("my_skin");
   my_generator.add_view<my_skin::message,content::message>("message",true);
    cppcms::views::pool::instance().add(my_generator);
 }
 ~loader() {  cppcms::views::pool::instance().remove(my_generator); }
} a_loader;
} // anon 

 

回答上述问题:

1. view的语义是定义一个基类cppcms::base_view的子类,以及该子类所关联的model数据, 关联的model数据实际上被定义类该子类的成员变量。

2. template的语义是定义上述子类中的一个函数,后跟函数名(函数返回值实际上是该函数的第一个参数[输出流])。虽然render()这个函数名与my_hello_world application中的render()函数名称相同,但是毫无关系。

3. skin的语义是定义个一个命名空间。

 

这样,我个人觉得上述的render api定义,应该是view的名称,而不是模板名称。因为c++代码中,并没有template name这个概念。如果有,也是函数名称。

 

另外,需要注意的是翻译后c++代码中下面的部分,cppcms框架中定义了一个view池实例,池中包含cppcms::views::generator(view生成器),每个生成器(skin的名称,就是每个generator的名称)可以产生若干不同的view,通过调用add_view即可,并且加入view时,应给予一个一一对应名称。(猜想方便后续application的调用) 

template<typename View, typename Content>
void cppcms::views::generator::add_view(std::string const& view_name,
bool safe=true)

/*
Add a single view of type View that uses content of type Content Using name view_name.

If safe is true that dynamic cast is used to ensure that content has proper type otherwise static cast.

Usually used by templates generator
*/

 

结论:

 

1. struct class_name : public cppcms::base_content 定义model data

2. <% view view_name uses content::data %>定义cppcms::base_view的一个子类,content::data被声明为该子类的一个成员。

        3.<% template xxx() %> 定义2给出的子类中的一个函数,函数的返回中通常为一个输出流(即render后的html代码)

4. cppcms框架中定义个一个view池,view池中包含的对象是cppcms::views::generator对象,generator的名称是skin的名称,每个generator可以生成若干view。add_view<view_type, content>("view_name", true). 

分享到:
评论

相关推荐

    初识JVM – JVM概念.pdf

    ### 初识JVM – JVM概念 #### 一、JVM简介 JVM,即Java Virtual Machine(Java虚拟机),是一种能够执行特定机器指令的虚拟机。它通过软件模拟了一个完整的计算机系统,允许Java程序在任何支持JVM的平台上运行而...

    初识C++ 初识C++

    初识C++ 初识C++ 初识C++初识C++初识C++初识C++初识C++

    19 STL初识-STL的基本概念

    19 STL初识-STL的基本概念

    Java开发学习(一)----初识Spring及其核心概念.doc

    本文将深入探讨Spring框架的核心概念,包括它的系统架构以及如何通过IOC(Inversion of Control)和DI(Dependency Injection)来解决编程中遇到的问题。 首先,Spring框架的系统架构分为几个主要部分: 1. **核心...

    初识云计算.ppt

    初识云计算初识云计算初识云计算初识云计算初识云计算初识云计算初识云计算初识云计算

    python初识

    python 列表初识,通过此代码,你能够了解到python的列表操作

    操作系统实验报告实验一 WINDOWS进程初识

    #### 实验一:Windows 进程初识 ##### 实验目的 1. **学会使用VC编写基本的Win32 Console Application(控制台应用程序)**: - 通过本实验,学生将了解如何在Visual C++ 6.0环境中创建控制台应用程序。 - 掌握...

    初识excel教学设计

    【初识Excel教学设计】 Excel是一款广泛应用于数据管理和分析的电子表格软件,对于初学者来说,理解其基本功能和操作是至关重要的。本教学设计针对初中信息技术课程,旨在引导初一学生逐步熟悉Excel,帮助他们建立...

    jvm初识及JIT优化

    jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识...

    初识Java_课后补充作业

    12. **泛型**:理解泛型的作用,如何在类、接口、方法中使用泛型,以及通配符的概念。 13. **注解**:注解在代码中提供了元数据,学习标准注解和自定义注解的使用。 通过“初识Java_课后补充作业”的深入练习,...

    三年级信息技术课程初识画图

    三年级信息技术课程《初识画图》课件内容 因为要参加比赛,所属机房 装不上

    初识计算机PPT课件.pptx

    "初识计算机PPT课件" 计算机的基本概念: 计算机是一种电子设备,能够执行用户的指令,进行数据处理和存储。计算机的种类很多,可以分为台式计算机、便携式计算机、掌上计算机等。 台式计算机: 台式计算机是一...

    《初识数据结构》教学建议.pdf

    ### 数据结构的基本概念 数据结构是计算机存储、组织数据的方式。它旨在使数据的存取和处理更加高效。数据结构通常由数据对象和数据关系两部分构成。数据对象是指具有相同数据类型的元素的集合;数据关系则定义了...

    初识A寻路算法

    标题中的“初识A*寻路算法”表明我们要探讨的是计算机科学中的一种路径搜索算法——A*(A-star)算法。A*算法是Dijkstra算法的优化版本,广泛应用于游戏开发、地图导航、网络路由等领域,它通过引入启发式信息来实现...

    2020—2021学年浙教版(2020)七年级下册教案-第13课初识数据结构.pdf

    根据提供的文件内容,本节课的主要内容是让学生初识数据结构,并理解算法的三种基本控制结构,包括顺序结构、分支结构和循环结构。同时,通过与学生生活紧密相关的实例,引导学生认识数据结构的概念和常见的数据结构...

    01_服务器的基本概念与初识Ajax

    服务器的基本概念与初识Ajax 本资源摘要信息将对服务器的基本概念、URL地址、客户端与服务器的通信过程、服务器对外提供的资源和Ajax技术进行详细的阐述。 一、客户端与服务器 在互联网时代,用户通过客户端(如...

    Java基础精品课01-初识java录屏1.java概念简介.mp4

    Java基础精品课01-初识java录屏1.java概念简介.mp4

    MATLAB初识神经网络

    这个“MATLAB初识神经网络”视频教程是为那些想要入门神经网络学习者设计的,它将引导你逐步了解神经网络的基本概念和MATLAB中的实现方法。 神经网络,作为人工智能的重要分支,模仿了人脑的结构和功能,通过大量的...

    Maven初识,核心概念,构建多模块系统

    Maven的核心概念中,依赖管理是非常重要的一个部分。依赖管理主要处理项目依赖关系的复杂性,包括依赖传递性、依赖范围、依赖冲突解决方案和依赖排除等方面。依赖传递性指如果A依赖B,而C又依赖A,则C也会间接依赖B...

    初识JavaScript(源代码)

    初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识JavaScript(源代码)初识...

Global site tag (gtag.js) - Google Analytics