pos機(jī)301代碼,Python大神教你300行代碼搞定HTML模板渲染「附源碼」

 新聞資訊2  |   2023-06-24 11:15  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于pos機(jī)301代碼,Python大神教你300行代碼搞定HTML模板渲染「附源碼」的知識,也有很多人為大家解答關(guān)于pos機(jī)301代碼的問題,今天pos機(jī)之家(www.dsth100338.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機(jī)301代碼

pos機(jī)301代碼

一、前言

模板語言由HTML代碼和邏輯控制代碼組成,此處 @PHP 。通過模板語言可以快速的生成預(yù)想的HTML頁面。應(yīng)該算是后端渲染不可缺少的組成部分。

二、功能介紹

通過使用學(xué)習(xí) tornado 、 bottle 的模板語言,我也效仿著實現(xiàn)可以獨立使用的模板渲染的代碼模塊,模板語法來自 tornadobottle 的語法??梢杂脕碜鲆恍┖唵蔚氖虑?網(wǎng)頁渲染 , 郵件內(nèi)容生成 等HTML顯示方面。以下就是簡單的語法使用介紹。

1. 變量。使用 {{ }} 包裹起來,里面的變量為Python傳入。模板渲染時會將傳入的變量轉(zhuǎn)換成字符串并填入對應(yīng)位置。

# 模板文件內(nèi)容<title>{{my_title}}</title><label>{{ session.name }}</label># py代碼調(diào)用 t_html 為上面的內(nèi)容Template(t_html).render(my_title="標(biāo)題", session = some_obj)

2. 轉(zhuǎn)義。默認(rèn)傳入的數(shù)據(jù)都會進(jìn)行HTML轉(zhuǎn)義,可以使用 {% raw value %} 來將value的內(nèi)容按原始字符串輸出。

# 模板文件內(nèi)容<p>{% raw value %} </p># Py調(diào)用內(nèi)容Template(t_html).render(my_title="<label>顯示標(biāo)簽</label>")

3. 條件控制。支持Python的 if,elif,else 。條件代碼需要放在 {% %} 內(nèi)部,并且在條件結(jié)束后需要額外增加 {% end %} ,用于標(biāo)識條件控制語句塊范圍。

# 模板文件內(nèi)容{% if a > 1%}<label>A大于1</label>{% else %}<label>A小于或等于1</label>{% end %}# py調(diào)用Template(t_html).render(a=1)

4. 循環(huán)控制。支持Python的 forwhile 。與條件控制一樣也需要放在 {% %} 內(nèi)部,并且結(jié)束處需要額外增加 {% end %} ,用于標(biāo)識循環(huán)控制語句塊的范圍。

# 模板文件內(nèi)容{% for i in range(10) %} <label>當(dāng)前序號:{{i+1}}</label>{% end %}# py調(diào)用Template(t_html).render()

5. 變量聲明。如果需要在模板文件內(nèi)聲明一個變量,方便使用時,可以通過 set 來實現(xiàn)。具體格式為 {% set v = xx %} 。通過 set 聲明的變量在整個模板文件中都可以使用,包括在條件控制和循環(huán)控制中作為條件判斷也可以。

# 模板文件內(nèi)容{% set a = 1 %}<label>a的值:{{a}}</label>三、源碼

這個模板語言模塊是在 Python2.7 上面開發(fā)使用的,如果要在 Python3+ 上使用需要對 strbytes 進(jìn)行一些處理即可,由于沒有引用任何其他模塊,可以很好地獨立使用。

1 # -*- coding:utf-8 -*- 2 3 """ 模板語言""" 4 5 # TOKEN相關(guān)的定義 6 TOKEN_S_BRACE = "{" 7 TOKEN_S_BLOCK = "%" 8 TOKEN_EXPRESSION_L = "{{" 9 TOKEN_EXPRESSION_R = "}}" 10 TOKEN_BLOCK_L = "{%" 11 TOKEN_BLOCK_R = "%}" 12 TOKEN_KEY_SET = "set" 13 TOKEN_KEY_RAW = "raw" 14 TOKEN_KEY_IF = "if" 15 TOKEN_KEY_ELIF = "elif" 16 TOKEN_KEY_ELSE = "else" 17 TOKEN_KEY_FOR = "for" 18 TOKEN_KEY_WHILE = "while" 19 TOKEN_KEY_END = "end" 20 TOKEN_KEY_BREAK = "break" 21 TOKEN_KEY_CONTINUE = "continue" 22 TOKEN_SPACE = " " 23 TOKEN_COLON = ":" 24 # Token標(biāo)記 {{}} {% %} 25 TOKEN_FLAG_SET = {TOKEN_S_BRACE, TOKEN_S_BLOCK} 26 # 簡單的語句 27 TOKEN_KEY_SET_SIMPLE_EXPRESSION = {TOKEN_KEY_SET, TOKEN_KEY_RAW} 28 # 前置條件 29 TOKEN_KEY_PRE_CONDITION = { 30 # end 必須在if/elif/else/for/while 后面 31 TOKEN_KEY_END: {TOKEN_KEY_IF, TOKEN_KEY_ELIF, TOKEN_KEY_ELSE, 32 TOKEN_KEY_FOR, TOKEN_KEY_WHILE}, 33 # elif 必須在if 后面 34 TOKEN_KEY_ELIF: {TOKEN_KEY_IF}, 35 # else 必須在if/elif 后面 36 TOKEN_KEY_ELSE: {TOKEN_KEY_IF, TOKEN_KEY_ELIF, TOKEN_KEY_FOR, TOKEN_KEY_WHILE}, 37 } 38 # 循環(huán)語句 39 TOKEN_KEY_LOOP = {TOKEN_KEY_WHILE, TOKEN_KEY_FOR} 40 # 循環(huán)的控制break continue 41 TOKEN_KEY_LOOP_CTRL = {TOKEN_KEY_BREAK, TOKEN_KEY_CONTINUE} 42 43 class ParseException(Exception): 44 pass 45 46 class TemplateCode(object): 47 def __init__(self): 48 self.codeTrees = {"parent": None, "nodes": []} 49 self.cursor = self.codeTrees 50 self.compiled_code = None 51 52 def create_code(self): 53 """創(chuàng)建一個代碼子塊""" 54 child_codes = {"parent": self.cursor, "nodes": []} 55 self.cursor["nodes"].append(child_codes) 56 self.cursor = child_codes 57 58 def close_code(self): 59 """ 關(guān)閉一個代碼子塊 """ 60 assert self.cursor["parent"] is not None, "overflow" 61 self.cursor = self.cursor["parent"] 62 63 def append_text(self, text): 64 """ 添加文本 """ 65 # 排除空行 66 self.cursor["nodes"].append("_add(%r)" % text) 67 68 def append_express(self, express, raw=False): 69 """ 表達(dá)式 """ 70 if raw: 71 temp_exp = "_t_exp = _str_(%s)" % express 72 else: 73 temp_exp = "_t_exp = _esc_(%s)" % express 74 self.cursor["nodes"].append(temp_exp) 75 self.cursor["nodes"].append("_add(_t_exp)") 76 77 def append_statement(self, statement): 78 """ 語句 """ 79 temp_statement = "%s" % statement 80 self.cursor["nodes"].append(temp_statement) 81 82 def reset(self): 83 self.codeTrees = {"parent": None, "nodes": []} 84 self.cursor = self.codeTrees 85 self.compiled_code = None 86 87 def build_code(self, filename): 88 temp_code_buff = [] 89 self.write_buff_with_indent(temp_code_buff, "def _template_render():", 0) 90 self.write_buff_with_indent(temp_code_buff, "_codes = []", 4) 91 self.write_buff_with_indent(temp_code_buff, "_add = _codes.append", 4) 92 self.write_codes(temp_code_buff, self.codeTrees, 4) 93 self.write_buff_with_indent(temp_code_buff, "return ''.join(_codes)", 4) 94 temp_code = "".join(temp_code_buff) 95 self.compiled_code = compile(temp_code,filename, "exec", dont_inherit=True) 96 97 def write_codes(self, code_buff, codes, indent): 98 for node in codes.get("nodes", []): 99 if isinstance(node, dict):100 self.write_codes(code_buff, node, indent+4)101 else:102 self.write_buff_with_indent(code_buff, node, indent)103 104 def generate(self, **kwargs):105 temp_namespace = {}106 temp_namespace['_str_'] = self.to_utf8107 temp_namespace['_esc_'] = self.to_safe_utf8108 temp_namespace.update(kwargs)109 exec(self.compiled_code, temp_namespace)110 return temp_namespace['_template_render']()111 112 @staticmethod113 def write_buff_with_indent(code_buff, raw_str, indent):114 """"""115 temp = (" " * indent) + raw_str + "\"116 code_buff.append(temp)117 118 @staticmethod119 def to_utf8(raw_str):120 """ 轉(zhuǎn)換 """121 if isinstance(raw_str, str):122 return raw_str123 elif isinstance(raw_str, bytes):124 return raw_str.decode()125 return str(raw_str)126 127 @staticmethod128 def to_safe_utf8(raw_str):129 """ 過濾html轉(zhuǎn)義 """130 text = TemplateCode.to_utf8(raw_str)131 return text.replace("&", "&").replace("<", "<").replace(">", ">")132 class Template(object):133 """模板類"""134 def __init__(self, input_obj,filename="<string>", **namespace):135 """模板初始化"""136 self.namespace = {}137 self.namespace.update(namespace)138 # 將數(shù)據(jù)丟進(jìn)去解析生成編譯代碼139 self.lexer = TemplateLexer(input_obj, filename)140 141 def render(self, **kwargs):142 """渲染模板 """143 temp_name_space = {}144 temp_name_space.update(self.namespace)145 temp_name_space.update(kwargs)146 # 執(zhí)行渲染147 return self.lexer.render(**kwargs)148 149 class TemplateLexer(object):150 """模板語法分析器 """151 def __init__(self, input_obb, filename="<string>"):152 if hasattr(input_obb, "read"):153 self.raw_string = input_obb.read()154 else:155 self.raw_string = input_obb156 self.filename = filename157 # 記錄當(dāng)前的位置158 self.pos = 0159 # 記錄原始數(shù)據(jù)的總長度160 self.raw_str_len = len(self.raw_string)161 # 記錄解析的數(shù)據(jù)162 self.code_data = TemplateCode()163 # 開始解析164 self.parse_template()165 166 def match(self, keyword, pos=None):167 return self.raw_string.find(keyword, pos if pos is not None else self.pos)168 169 def cut(self, size=-1):170 """剪取數(shù)據(jù) size切割數(shù)據(jù)的大小,-1表示全部"""171 if size == -1:172 new_pos = self.raw_str_len173 else:174 new_pos = self.pos + size175 s = self.raw_string[self.pos: new_pos]176 self.pos = new_pos177 return s178 179 def remaining(self):180 """獲取剩余大小 """181 return self.raw_str_len - self.pos182 183 def function_brace(self):184 """ 獲取{{ / {% """185 skip_index = self.pos186 while True:187 index = self.match(TOKEN_S_BRACE, skip_index) # {% {{188 # 沒找到189 if index == -1:190 return None, -1191 # 末尾192 if index >= self.raw_str_len:193 return None, -1194 # 匹配類型195 next_value = self.raw_string[index + 1:index + 2]196 if next_value not in TOKEN_FLAG_SET:197 skip_index = index + 1198 # 說明不是關(guān)鍵類型199 continue200 brace = self.raw_string[index: index + 2]201 return brace, index202 return None, -1203 204 def read_content_with_token(self, index, begin_token, end_token):205 """206 讀取匹配token的內(nèi)容207 """208 end_index = self.match(end_token)209 if end_index == -1:210 return ParseException("{0} missing end token {1}".format(begin_token, end_token))211 # 過濾 begin_token212 self.pos = index + len(begin_token)213 content = self.cut(end_index - self.pos)214 # 去除末尾 end_token215 self.cut(len(end_token))216 return content217 218 def add_simple_block_statement(self, operator, suffix):219 if not suffix:220 raise ParseException("{0} missing content".format(operator))221 if operator == TOKEN_KEY_SET:222 self.code_data.append_statement(suffix)223 elif operator == TOKEN_KEY_RAW:224 self.code_data.append_express(suffix, True)225 else:226 raise ParseException("{0} is undefined".format(operator))227 228 def parse_template(self):229 """解析模板 """230 # TODO 檢查模板文件是否更改過,如果沒有則不需要重新解析231 self.code_data.reset()232 # 解析模板原文件233 self.__parse()234 # 生成編譯code235 self.__compiled_code()236 237 def render(self, **kwargs):238 return self.code_data.generate(**kwargs)239 240 def __parse(self, control_operator=None, in_loop=False):241 """開始解析"""242 while True:243 if self.remaining() <= 0:244 if control_operator or in_loop:245 raise ParseException("%s missing {%% end %%}" % control_operator)246 break247 # 讀取 {{ {%248 brace, index = self.function_brace()249 # 說明沒有找到250 if not brace:251 text = self.cut(index)252 self.code_data.append_text(text)253 continue254 else:255 text = self.cut(index - self.pos)256 if text:257 self.code_data.append_text(text)258 259 if brace == TOKEN_EXPRESSION_L:260 content = self.read_content_with_token(index, TOKEN_EXPRESSION_L, TOKEN_EXPRESSION_R).strip()261 if not content:262 raise ParseException("Empty Express")263 self.code_data.append_express(content)264 continue265 elif brace == TOKEN_BLOCK_L:266 content = self.read_content_with_token(index, TOKEN_BLOCK_L, TOKEN_BLOCK_R).strip()267 if not content:268 raise ParseException("Empty block")269 270 # 得到表達(dá)式 for x in x ; if x ; elif x ; else ; end ; set ; while x ;271 operator, _, suffix = content.partition(TOKEN_SPACE)272 if not operator:273 raise ParseException("block missing operator")274 275 suffix = suffix.strip()276 # 簡單語句,set / raw277 if operator in TOKEN_KEY_SET_SIMPLE_EXPRESSION:278 self.add_simple_block_statement(operator, suffix)279 elif operator in TOKEN_KEY_LOOP_CTRL:280 if not in_loop:281 raise ParseException("{0} must in loop block".format(operator))282 self.code_data.append_statement(operator)283 else:284 # 控制語句 檢查匹配if 后面可以跟elif/else285 pre_condition = TOKEN_KEY_PRE_CONDITION.get(operator, None)286 if pre_condition:287 # 里面就是elif/else/end288 if control_operator not in pre_condition:289 raise ParseException("{0} must behind with {1}".format(operator, pre_condition))290 elif operator == TOKEN_KEY_END:291 # 遇到{% end %}則結(jié)束292 self.code_data.close_code()293 return294 else:295 # 由于是依據(jù)if 進(jìn)入 來計算elif ,因此elif與if是同級的296 self.code_data.close_code()297 self.code_data.append_statement(content + TOKEN_COLON)298 self.code_data.create_code()299 self.__parse(operator, in_loop or (operator in TOKEN_KEY_LOOP))300 break301 # 添加控制語句及內(nèi)部語句體 if for while302 self.code_data.append_statement(content + TOKEN_COLON)303 self.code_data.create_code()304 self.__parse(operator, in_loop or (operator in TOKEN_KEY_LOOP))305 else:306 raise ParseException("Unkown brace")307 return308 309 def __compiled_code(self):310 """生成 編譯code """311 self.code_data.build_code(self.filename)312 if __name__ == "__main__":313 t = Template("<html>{{hello}}</html>")314 t.render(hello="你好"

原文鏈接: http://www.cnblogs.com/jeffxun/p/15585073.html

以上就是關(guān)于pos機(jī)301代碼,Python大神教你300行代碼搞定HTML模板渲染「附源碼」的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機(jī)301代碼的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://www.dsth100338.com/newsone/72764.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。