Strana是一个模板引擎,灵感来自Jinja2
Strana的Python项目详细描述
斯特拉娜
受django模板系统启发的python模板引擎
strana是一个模板引擎,使用它可以很容易地使用模板生成文本文件。 它使用的技术灵感来自于django的模板系统,并进行了一些小的调整。
安装
从"发布"选项卡下载发布tarball并运行
pip install strana
示例
fromStrana.contextimportContextfromStrana.templateimportTemplatesource="I'm such a {= quality =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Ouput: I'm such a good boy
如你所见,{=…=}告诉解析器里面的东西实际上是一个变量。 解析器一旦遇到这个块,就会在上下文中搜索变量。 上下文是字典周围的一个特殊包装器,它提供对变量的访问。 这里,"quality"变量存在于上下文中,值为"good"。
再举一个例子
source="I'm such a {= quality.0 =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':['good','bad']},'root')))#Outputs: I'm such a good boy
如您所见,quality.0被转换为quality[0]。 字典呢?
source="I'm such a {= quality.aniket =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':{'aniket':'good'}},'root')))#Output: I'm such a good boy
您也可以使用简单的方法调用
source="I'm such a {= quality.get =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':{'get':lambda:'good'}},'root')))#Output: I'm such a good boy
但是,不能有带参数的方法。
继续前进,
source="I'm such a {= quality =}{# This is a comment #} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Output: I'm such a good boy
{…#}是一个注释,被忽略(这不是很明显吗?)
现在最重要的部分是行动
source=""" {> do 5 times <} I'm such a {= quality =} boy {> /do <}"""t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#OutputI'm such a good boyI'm such a good boyI'm such a good boyI'm such a good boyI'm such a good boy
动作标记跨越多行,可以修改输出,如示例中所示 "do 5 times"标记告诉解析器重复其主体5次。我们将了解如何编写自己的操作
这些都是基本的例子。为了进入高级,我们需要一些概念
概念
变量
你已经知道它们是什么了。它们类似于普通的python变量,并且可选地可以是可索引的。
修饰语
修饰符是可选的"函数",可以访问变量的值并对其进行修改。他们可以选择接受争论。 假设我们调用了modifier,它可以将变量转换为大写,并接受一个参数 如果为真,将只大写第一个字母,否则将大写整个值。 这就是我们使用它的方法-
source="I'm such a {= quality>>up=>False =} boy"
">>;"告诉解析器接下来的内容是一个修饰符,=>;告诉解析器下一部分是一个参数 我们将了解如何编写自己的修饰符。
操作
我们已经看到他们的行动(双关语)。它们基本上是可以随意访问主体和上下文的函数 使输出改变。我们将很快看到如何编写自己的操作。
库
这个类负责充当修饰符和动作的集合。您可以编写自己的修饰符和操作并注册它们 使用库并将库传递到模板。
发动机
它们是可选的帮助类,有助于模板加载和错误打印。 可以指定引擎的路径、要显示的错误字符串和库。下一次,您只需将模板文件的名称传递给引擎, 它将加载到正确的库中。
节点
把节点想象成盒子,其中存储了一些数据。解析时,每个变量、注释和操作 转换为节点。每个节点都有一个id。在渲染时,调用这些节点的render方法,该方法返回相应节点的输出 节点。您可以编写自己的节点,尽管这可能不是必需的。
这是一个对dict的包装。除了提供对变量的访问之外,它还做了一些我们很快就会看到的事情。
模板
这是系统的核心。这个类基本上是解析节点的集合。 传递上下文并给出输出。相同的模板可以在不同的上下文中呈现。
高级用法
使用发动机
在大多数情况下,使用DefaultEngine类就足够了。这个类为您提供 为您提供了两个基本的内置标记-"for i in x"和"do i times"标记。 您应该仅使用此类提供模板路径。对于您自己的库,将它们传递到模板。
fromStrana.engineimportDefaultEnginefromStrana.templateimportTemplateen=DefaultEngine('templates')source="{> do 2 times <}HI{>/do}"现在P>使用引擎的加载模板方法加载模板。 模板的扩展名应为".ptm"。如果是其他东西,请传递全名
pip install strana
0
使用库并编写自己的操作
在开始编写操作之前,让我们看一看不同类型的操作
- 基本操作:它们很简单,不带任何参数,只有一行,可以在上下文中保存输出,并执行真正简单的任务 (例如打印时间)
- 循环操作:这些操作跨越多行,可以访问其中的任何内容,并需要一个结束标记。
- 图案标签:这些标签可以匹配自定义图案,例如"给我看你的标记"或"做n次"
现在,让我们看看它们的每一个动作。
首先导入库类并创建一个实例
pip install strana
1
现在要注册基本操作,请使用basic_action()函数。
每个操作都必须将节点id作为第一个参数。
pip install strana
2
您可以使用"as"关键字保存输出并在以后使用它
pip install strana
3
要注册循环操作,您将使用循环操作方法。 必须为该方法指定一个名称,该名称将标识操作的名称 例如,一个基本的if操作-
pip install strana
4
如您所见,操作的参数是空格分隔的。此外,还需要一个结束标记。 结束标记后面紧跟着姓名。
现在,该开始模式操作了。
要注册模式操作,您将使用pattern_action方法。此方法需要名称参数 就像其他人一样,如果您想要访问主体,则需要一个need_context参数和一个need_body参数。 此外,还需要模式参数。模式可以是任何字符串。您将使用<;>;作为参数。 在运行时,将对模式进行mathced,并且将以字符串形式传递代替<;gt;的任何mathces。
说你的模式是"做<;>;次"。记住,模式必须以传递给name参数的任何内容开头。
现在,你写{>;做8次<;}。
当解析器遇到这一行时,它用"8"作为参数调用操作。注释 它是作为字符串传递的。由函数将其更改为正确的类型。
如果need_context为true,则传递context,第三个参数必须命名为context。
如果need_body为true,则需要结束标记,第二个参数必须为body。
这是"do n times"模式的代码。它生成一个名为"iteration"的变量 它保存当前迭代的值,并且仅存在于此块中。
pip install strana
5
写入修饰符
要编写修饰符,我们将使用register_修饰符方法。此方法还接受name参数 还有一个函数。此函数的第一个参数必须是要修改的值。 任何附加参数都将遵循此操作。
下面是up修饰符的代码
pip install strana
6
当你这样称呼它时
pip install strana
7
某些变量的值作为第一个参数传递。
要提供第一个字母参数,您将编写此-
pip install strana
8
内置库
内置库为您提供了两个有用的操作。
一个是abov所说的"do n times",另一个是"for i in l"动作, 这正是你所期望的。
使用上下文
Context类为管理变量的dict提供了一个有用的包装器。(i 已经说过两次了)。要启动上下文,您需要首先导入类。
pip install strana
9
然后传递一个引擎、一个包含变量的dict和一个节点id。 此节点ID可以是任何字符串。通常,对于起始上下文,我们使用"根"。
fromStrana.contextimportContextfromStrana.templateimportTemplatesource="I'm such a {= quality =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Ouput: I'm such a good boy0
如果您打印CTX,您将看到这个-
fromStrana.contextimportContextfromStrana.templateimportTemplatesource="I'm such a {= quality =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Ouput: I'm such a good boy1
注意"内置"部分。这三个是给你的。那不是很可爱吗?
另外,请注意上下文绑定到节点"root"。每当节点添加som时新的变量,它必须将自己绑定到上下文。 别担心,这是自动发生的。
此时,您只能使用两种方法-
- 临时按下
- 按下"永久"
push_temporary返回当前上下文的副本,其中添加了一些新变量。如果需要一些变量,这很有用 只在一个街区内。
还记得"做N次"的动作吗?当然没有。这是密码。
fromStrana.contextimportContextfromStrana.templateimportTemplatesource="I'm such a {= quality =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Ouput: I'm such a good boy2
仔细看一下-
fromStrana.contextimportContextfromStrana.templateimportTemplatesource="I'm such a {= quality =} boy"t=Template(source,None,None)print(t.render(Context(None,{'quality':'good'},'root')))#Ouput: I'm such a good boy3
push_permanent按一个持续到结束的dict。
context类还提供了一个pop_last方法,该方法将弹出它绑定到的最后一个节点。 用户不应该使用它(此时它也没有实际用途)。
作者
- 阿尼基特·巴塔查耶
许可证
本项目在GNU通用公共许可v3下获得许可