视图全局变量、构建器和过滤器
查看合成器、共享和筛选器
简介
您经常会发现自己一次又一次地向视图中添加相同的变量。这可能类似于
from masonite.request import Request
def show(self, request: Request):
return view('dashboard', {'request': request})
def another_method(self):
return view('dashboard/user', {'request': request})
这很快就会变得烦人,如果同一个变量在所有的模板中都可以使用的话,那就简单多了。为此,我们可以使用 View 类与我们的所有模板 「共享」一个变量。
视图共享
我们可以通过在 .share()
方法中简单地指定变量来与所有模板共享变量,如下所示:
from masonite.view import View
...
def boot(self, view: View)
view.share({'request': request()})
最好的放置位置是在一个新的服务提供者中。让我们现在创建一个名为 ViewComposer
的对象。
$ craft provider ViewComposer
这将在 app/providers/ViewComposer.py
下创建一个新的服务提供者,如下所示:
class ViewComposer(ServiceProvider):
def register(self):
pass
def boot(self):
pass
我们也不需要它在每个请求上运行,因此我们可以将 wsgi
设置为 False
。这样做只会在服务首次启动时运行此提供程序。这将最小化每个请求所需的开销:
class ViewComposer(ServiceProvider):
wsgi = False
def register(self):
pass
def boot(self):
pass
真棒!
由于我们需要该请求,因此可以将其放入 boot
方法中,该方法可以访问在服务容器中注册的所有内容,包括 Request
类。
from masonite.request import Request
from masonite.view import View
class ViewComposer(ServiceProvider):
wsgi = False
def register(self):
pass
def boot(self, view: View, request: Request):
view.share({'request': request})
最后,我们需要将此文件加载到 config/application.py
文件中的 PROVIDERS
列表中。
from app.providers.ViewComposer import ViewComposer
PROVIDERS = [
# Framework Providers
...
ViewProvider,
HelpersProvider,
...
# Third Party Providers
...
# Application Providers
ViewComposer, # <- New Service Provider
]
我们做完了这些!下次启动服务器时,request
变量将在所有模板上可用。
查看合成器
除了与所有模板共享这些变量外,我们还可以仅指定某些模板。所有步骤将完全相同,只是要使用 .composer()
方法来代替 .share()
方法:
def boot(self, view: View, request: Request):
view.composer('dashboard', {'request': request})
现在,任何时候访问 dashboard
模板 (位于 resources/templates/dashboard.html
) , request
变量都可用。
我们还可以指定几个模板,它们与上面的功能相同,但这次使用的是resources/templates/dashboard.html
模板和 resources/templates/dashboard/user.html
模板:
def boot(self, view: View, request: Request):
view.composer(['dashboard', 'dashboard/user'], {'request': request})
最后,我们可以为所有模板编写一个字典:
def boot(self, view: View, request: Request):
view.composer('*', {'request': request})
请注意,此行为与
ViewClass.share()
完全相同
查看过滤器
Jinja2 允许向视图添加过滤器。在说明如何向所有模板添加过滤器之前,让我们明确地解释什么是视图过滤器。
什么是过滤器?
筛选器可以附加到视图变量,以便更改和修改它们。例如,您可能有一个要转换为 slug 的变量,其内容如下:
{{ variable|slug }}
在 Python 中,这个 slug 过滤器只是一个将变量作为参数的函数,看起来像一个简单的函数,如下所示:
def slug(variable):
return variable.replace(' ', '-')
就是这样!重要的是要注意,它要过滤的变量始终作为第一个参数传递,而所有其他参数都在其后,因此我们可以执行以下操作:
{{ variable|slug('-') }}
然后我们的函数将如下所示:
def slug(variable, replace_with):
return variable.replace(' ', replace_with)
添加过滤器
我们可以使用 ViewClass
类上的 filter
方法简单地添加过滤器。这看起来像:
from masonite.view import View
class UserModelProvider(ServiceProvider):
"""Binds the User model into the Service Container."""
wsgi = False
...
def boot(self, view: View):
view.filter('slug', self.slug)
@staticmethod
def slug(item):
return item.replace(' ', '-')
确保在设置为
wsgi = False
的 [服务提供者](../ architectural-concepts / service-providers.md) 中添加过滤器。这样可以防止在不需要的每个请求上添加过滤器。
如此而已!添加过滤器非常简单!
查看测试
查看测试只是可以在模板中使用的自定义布尔表达式。我们可能希望对特定对象运行布尔测试,以断言它们通过了测试。例如,我们可能希望测试用户是否为如下公司的所有者:
<div>
{% if user is a_company_owner %}
hey boss
{% else %}
you are an employee
{% endif %}
</div>
为此,我们需要在 View
类上添加一个测试。我们可以在服务提供者中做到这一点。您选择的服务提供者最好应具有 wsgi=False
属性,这样就不会在每个请求上都添加测试,那可能会降低应用程序的速度。
代码很简单,看起来像这样:
from masonite.view import View
...
def a_company_owner(user):
# Returns True or False
return user.owner == 1
class SomeProvider:
wsgi = False
...
def boot(self, view: View):
# template alias
view.test('a_company_owner', a_company_owner)
就是这样!现在,我们可以在模板中使用 a_company_owner
,就像上面的第一个代码片段一样!
请注意,我们只提供了函数,没有实例化任何内容。我们提供的函数或对象需要有 1 个参数,该参数是我们正在测试的对象或字符串。
添加扩展
Jinja2 具有扩展的概念,您可以通过与 服务提供者 中先前的实现类似的方式轻松地将它们添加到项目中:
from masonite.view import View
class SomeProvider:
wsgi = False
...
def boot(self, view: View):
view.add_extension('pypugjs.ext.jinja.PyPugJSExtension')
这会将扩展添加到视图类。
请记住将其放置在
wsgi = False
的服务提供者中,因为这将阻止在每个请求上添加扩展。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。