大家好,今天来为大家分享css网站模板源码分享的一些知识点,和css制作网站的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!
介绍
cJinja是一个使用cpp编写的轻量html模版解析库,依赖ejson来实现模版的数据替换(在jinja中称为context,上下文)。模版的语法基本与djangojinja一致,功能还算丰富。源码仅有700行,适合学习,觉得不错的点个star吧。
(该程序为https://github.com/HuangHongkai/tinyserver中的一个模块)
编译
使用cmake来编译,windows和linux下均可编译。推荐使用clion作为IDE。
编译成功后在build目录下会有libcjinja.a和cjinja_test.exe这2个文件。libcjinja.a是静态库,cjinja_test.exe是一个简单的测试程序。
运行测试程序后会出现output.html(该文件是tmp.html解析后的结果。)
已经完成的功能
变量,例如{{var}}变量索引访问,例如{{var.var2}}{{var[2]}}{{var[2].key.value[2]}},其中**[]**表示对数组(类似python的list)进行索引,.表示对object进行索引(类似与python的dict)表达式计算(包括字符串拼接),例如{{1*1+2-3*var}}{{1+1*2-3/4}}{{“asdfsf”+var}}for-endfor对列表进行迭代,例如{%forvarinlist%}{%endfor%}for-endfor对对象进行迭代,例如{%forkey,valueinobject%}{%endfor%}或者{%forkeyinobject%}{%endfor%}或者{%for,valueinobject%}{%endfor%}if-else-endif语句,其中if的条件支持四则运算,简单的比较(!===)等,例如{%if1+1==2%}aaa{%else%}bbb{%endif%}模版包含,嵌套其他的模版文件{%include’other.html’%}模版语法错误提示
需要注意,表达式之间不能含有空格,例如{{1+1}}是非法的,而{{1+1}}是合法的。
使用方法
1.变量和变量索引
简单的例子如下,
HtmlTemplatehtml(“username:{{username}}\\n”\n”parm.list[1][2]:{{parm.list[1][2]}}\\n”\n”parm.key:{{parm.key}}”,\n1);//参数1表示传入的是模版字符串,0表示传入的是文件名,默认为0\nJSONObjectobj={\n{“username”,1234},\n{“parm”,{\n{“key”,”cde”},\n{“list”,{1,{1,2.3,”abcd”},”hahaha”}},\n}}\n};\nhtml.setValue(obj);\ncout<<html.render()<<endl<<endl;\n/*运行后打印如下\nusername:1234\nparm.list[1]:abcd\nparm.key:cde\n*/\n
HtmlTemplate是一个库的主要类,构造函数为
explicitHtmlTemplate(conststring&str,intflag=0);//flag=0是str表示文件路径,不为0是表示传入的模版字符串
其中str参数为字符串,可以表示html模板原始串,也可也表示为文件的路径,flag默认为0。
setValue方法表示传入数据给模版对象。
render()方法表示将模版解析成字符串。
JSONObject来源于ejson库,用来模拟python的dict,构造函数也比较容易看懂。
2.列表迭代
HtmlTemplatehtml(“{%forxinlist%}{{x}}\\n{%endfor%}”\n”此时x已经是临时变量了,不可以在打印了{{x}}\\n”\n,1);\nJSONObjectobj=OBJECT(\nKEYVALUE(“list”,LIST(1,2,3,4,5))\n);\ncout<<html.setValue(obj).render()<<endl<<endl;\n/*运行后输出如下\n1\n2\n3\n4\n5\n此时x已经是临时变量了,不可以在打印了\n*/\n
注意到在迭代过程中x是作为临时变量,在外部的话是无法打印出来的。
3.字典迭代
HtmlTemplatehtml(“{%forkeyindict%}迭代1:字典的key值为{{key}}\\n{%endfor%}”\n”{%forkey,valueindict%}迭代2:字典的key值为{{key}},value值为{{value}}\\n{%endfor%}”\n”{%for,valueindict%}迭代3:字典的value值为{{value}}\\n{%endfor%}”,1);\nJSONObjectobj=OBJECT(\nKEYVALUE(“dict”,OBJECT(\nKEYVALUE(“key1″,”value1”),\nKEYVALUE(“key2”,1234),\nKEYVALUE(“key3”,nullptr),\n))\n);\ncout<<html.setValue(obj).render()<<endl<<endl;\n/*运行后输出\n迭代1:字典的key值为key1\n迭代1:字典的key值为key2\n迭代1:字典的key值为key3\n迭代2:字典的key值为key1,value值为value1\n迭代2:字典的key值为key2,value值为1234\n迭代2:字典的key值为key3,value值为null\n迭代3:字典的value值为value1\n迭代3:字典的value值为1234\n迭代3:字典的value值为null\n*/\n
4.字符串拼接与表达式计算
HtmlTemplatehtml(“{{a+b+c+\\”444\\”}}\\n”\n”{{x}}*{{y}}+2*3-4/{{x}}={{x*y+2*3-4/x}}\\n”,\n1);\nJSONObjectobj=OBJECT(\nKEYVALUE(“a”,”111″),\nKEYVALUE(“b”,”222″),\nKEYVALUE(“c”,”333″),\nKEYVALUE(“x”,12),\nKEYVALUE(“y”,34)\n);\ncout<<html.setValue(obj).render()<<endl<<endl;\n/*运行后输出\n111222333444\n12*34+2*3-4/12=413.667\n*/\n
5.if-else-endif语句
HtmlTemplatehtml(“{%if1==1%}1==1成立{%else%}1==1不成立{%endif%}\\n”\n”{%if!x%}x为空{%else%}x不为空{%endif%}\\n”\n”{%ifx==2%}x==2成立{%endif%}\\n”\n”{%ifx+1!=2%}x+1!=2成立{%endif%}\\n”\n”{%ifx<3%}x<3成立{%endif%}\\n”\n”{%ifx>1%}x>1成立{%endif%}\\n”\n”{%ifstr==\\”abcd\\”%}str为abcd{%endif%}\\n”\n”{%if1%}常量表达式1{%endif%}\\n”\n”{%if0%}常量表达式0,此处不会输出{%endif%}”,1);\nJSONObjectobj={\n{“x”,2},\n{“str”,”abcd”}\n};\ncout<<html.setValue(obj).render()<<endl;\n/*运行后输出\n1==1成立\nx不为空\nx==2成立\nx+1!=2成立\nx<3成立\nx>1成立\nstr为abcd\n常量表达式1\n*/\n
6.for与if嵌套使用
HtmlTemplatehtml(“{%forxinlist%}”\n”{%ifx%}”\n”{%foryinlist2%}”\n”{{x}}*{{y}}={{x*y}}\\n”\n”{%endfor%}”\n”{%else%}”\n”x的值为空\\n”\n”{%endif%}”\n”{%endfor%}”,1);\nJSONObjectobj=OBJECT(\nKEYVALUE(“list”,LIST(1,2,3,4,5)),\nKEYVALUE(“list2”,LIST(1,2,3)),\n);\ncout<<html.setValue(obj).render()<<endl<<endl;\n/*运行后输出\n1*1=1\n1*2=2\n1*3=3\n2*1=2\n2*2=4\n2*3=6\n3*1=3\n3*2=6\n3*3=9\n4*1=4\n4*2=8\n4*3=12\n5*1=5\n5*2=10\n5*3=15\n*/\n
7.模版文件作为输出
HtmlTemplatehtml(“tmpl.html”);\nJSONObjectcontext=OBJECT(\n…\n);\nFILE*f=fopen(“output.html”,”w”);//写入到文件中\nstring&&str=html.setValue(context).render();\nfwrite(str.c_str(),1,str.size(),f);\nfclose(f);\n/*运行后,代开当前目录的tmpl.html文件作为输入,输出文件为output.html*/\n/*如果tmpl.html不存在则抛出异常*/\n
8.异常处理
HtmlTemplatehtml(“{%if1%}xxx”,1);\n//不传入context\ntry{\ncout<<html.render()<<endl;\n}catch(exception&e){\ncerr<<e.what()<<endl;\n}\ncout<<endl;\n
运行后终端上打印如下,
会提示异常的类名,异常文件所在位置,代码行数,以及一些错误的信息。
讨论
1.实现一个简单的表达式计算器用什么方法比较好?(例如{{2.3*3+4/5*x}}这类表达式)
我分享一下我自己的方法,有什么更好的方法一起讨论一下。
第一步,先把数据和符号提取出来放入到数组中,输入类型全部设为double。例如上面那个表达式,符号提取出来是{*,/,*},数据提取出来是{2.3,3,4,5,x}这一步位于__parse_var这个函数,比较简单不详细讨论。第二步,先计算乘除法,结果放入栈中,在对栈中元素计算加减法(按照我们平常计算表达式的思路先乘除后加减),这一步实现如下(其中运用到C语言的宏和C++11的匿名函数)
doublecJinja::HtmlTemplate::calculator(vector<any>&number,vector<char>&op){\n//例如下表达式会成为\n//1-2-3+2*3*4-4*5\n//vector<char>op={‘-‘,’-‘,’+’,’*’,’*’,’-‘,’*’};\n//vector<any>number={1,2,3,2,3,4,4,5};\nif(number.size()!=op.size()+1)\nthrowException(TemplateParseException,”运算符号数和操作数不匹配”);\n/*定义计算器的内部函数*/\nautocalc=[](any&var1,doublevar2,charop)->double{\n//var2+var1\n//var2*var1\n//var2-var1\n//var2/var1\n//注意顺序\nop2[0]==op){\\\nif(var1.type()==typeid(int))\\\nreturnvar2op2static_cast<double>(any_cast<int>(var1));\\\nelseif(var1.type()==typeid(float))\\\nreturnvar2op2static_cast<double>(any_cast<float>(var1));\\\nelseif(var1.type()==typeid(double))\\\nreturnvar2op2static_cast<double>(any_cast<double>(var1));\\\n}\nCALC(+);\nCALC(-);\nCALC(*);\nCALC(/);\nthrowException(TemplateParseException,”不允许对空指针进行运算”);\ndefinethrowException(Exception,…){\\\nstd::cerr<<“[“<<#Exception<<“]:FILE:”<<string(__FILE__).substr(string(__FILE__).find_last_of(‘/’)+1)<<“LINE:”<<__LINE__<<“FUNCTION:”<<__FUNCTION__<<std::endl;\\\nthrowException(__VA_ARGS__);\\\n}\n
其中__FILE__为文件名,__LINE__为当前代码行数,这些都是C中的内置宏,__VA_ARGS__是可变参数,对应于宏函数参数中的….
文章到此结束,如果本次分享的css网站模板源码分享和css制作网站的问题解决了您的问题,那么我们由衷的感到高兴!
