视图全局变量、构建器和过滤器

未匹配的标注
本文档最新版为 4.0,旧版本可能放弃维护,推荐阅读最新版!

查看合成器、共享和筛选器

简介

您经常会发现自己一次又一次地向视图中添加相同的变量。这可能类似于

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 的服务提供者中,因为这将阻止在每个请求上添加扩展。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/masonite/2.3/us...

译文地址:https://learnku.com/docs/masonite/2.3/us...

上一篇 下一篇
贡献者:2
讨论数量: 0
发起讨论 只看当前版本


暂无话题~