边栏搜索框的实现和模板共用-使用TEEBB快速搭建您的网站

您需要登录后才可观看此视频

为了更好的为您提供服务,请您登录后再查看本课程。

立即登录 注册账号

TEEBB提供了搜索block类型,在命令行中输入

symfony console debug:sonata:block

找到teebb.core.block.search类型,

>> teebb.core.block.search
    label                         ""
    translation_domain            "messages"
    template                      "@TeebbCore\/blocks\/search_form.html.twig"
    route                         "teebb_content_index"
    form_class                    ""
    property                      "title"
    extra                         {"fields":[]}

双击shift键,勾选右上角,我们查看系统自带的搜索block模板,模板提供了form表单,表单的action地址对应block类型的route参数。route是搜索页面的路由名称。form_class:是form表单的样式类。property:表单行的name。暂时忽略extra参数。

在对应代码位置,注释原有代码,使用sonata_block_render函数渲染搜索block类型, route参数输入search,现在还没有这个路由, 回到FrontController类创建search路由。

{{ sonata_block_render({type:'teebb.core.block.search'}, {
    route: 'search',
    template: 'blocks/search_form.html.twig'
}) }}

创建一个空的Action函数,直接复制index()进行修改,先修改路由路径和名称,修改render方法中的模板,对应的创建search_resuls.html.twig文件。 删除index和search方法的 controller_name参数。如果传入模板中的参数为空,可以省略。

回到动态列表页面,刷新! 搜索框已经出现了,但是样式和模板的不同,你可以复制html模板代码来定义自己的模板。在表单行中任意输入点文字、点击按钮。跳转到了search路由,并且表单行的数据以GET方式添加到了url后面。title就是搜索block类型的property参数。 现在,我们来完成搜索Action函数的功能。回到FrontController search函数。

讲些Symfony知识: Symfony作为MVC框架实现了PSR容器接口(弹出PSR文档),我们打开config目录下services.yaml文件, 在services键下方:src目录下的`exclude`配置以外的所有类都可以叫作“服务”,Entity目录下的类是Symfony框架的Model类型。 在_defaults键下方看到 autowireautoconfigure配置项,如果这两项为真,Symfony框架会将src目录中的类自动装配和自动配置并添加到Container容器中。在Container容器中的服务可以通过依赖注入的方式直接使用。

TEEBB也提供了很多服务,一般第三方Bundle中提供的服务都通过配置的形式添加到容器中,在TeebbCoreBundle -> Resources目录下的config目录中,你可以看到一些服务的具体配置。

回到FrontController类我们可以直接把容器中的服务依赖注入到Action函数中。

传入第一个参数,选择 HttpFoundation 组件提供的 Request 服务,Request对HTTP请求进行了封装,可以很方便的获取HTTP请求参数。

我们刚刚传入了title请求参数,输入:

$title = $request->get('title', '');

get的第二个参数是默认值,如果没有传入title参数则返回默认值。使用dd()方法来进行查看。

我们要根据传入的title值进行内容搜索,并且只对内容的标题进行模糊查询。现在注入第二个参数EntityManagerInterface $em,EntityManagerInterface接口的对象可以管理Entity对象在数据库中的数据,并提供了一些操作数据库的方法。

TEEBB中内容类型对应的Entity类是Content,获取Content类的Repository服务类,

    /**@var BaseContentRepository $baseContentRepository * */
    $baseContentRepository = $em->getRepository(Content::class);

BaseContentRepository类的createPaginator()方法可以按条件查询并将获取到的结果进行分页。第一个参数是查询条件,第二个参数是结果排序条件。

$criteria = ['bundle' => 'content'];
if ($title !== '') {
    $criteria = array_merge($criteria, ['title' => '%' . $title . '%']);
}

/**
* @var Pagerfanta $paginator
*/
$paginator = $baseContentRepository->createPaginator($criteria, ['id' => 'DESC']);

$paginator传入模板文件,也将当前的查询关键字传入模板,方便进行提醒。

查询到的结果页面样式和内容列表页的模板一样,将list_type_contents.html.twig 中的block区块代码复制到search_results.html.twig文件。

复制title block:

{% block title %}
    搜索"{{ keyword }}"结果
{% endblock %}

复制list_page_title 区块

{% block list_page_title %}
    <section id="topTitle" class="bg-light">
        <div class="container text-center">
            <div class="row pt-4">
                <div class="col-12">
                    <h1 class="font-weight-bold normal-title text-muted">
                        搜索"{{ keyword }}"结果
                    </h1>
                </div>
            </div>
            ...
        </div>
    </section>
{% endblock %}

复制粘贴content block中代码。 刷新页面,在右侧搜索框输入公告这是我们唯一的公告内容标题中包含的关键字。回车,结果显示了。 但是,模板文件中有大量代码重复了,我可以把列表页左右两侧的代码提取到单独的文件中。 创建content_list.html.twigside.html.twig文件。剪切并粘贴对应的代码。 在search_results.html.twig中对应位置引入这两个文件。

{% include 'front/content_list.html.twig' with _context %}
{% include 'front/side.html.twig' with _context %}

Twig中使用with关键字可以在include模板文件时对模板文件传入参数 _context关键字是当前页面的上下文数据,这样在模板文件中也可以使用当前页面的所有参数数据。

对应的我们修改list_type_contents.html.twig引入文件。 注意:在content_list.html.twig文件中,是通过对paginator参数进行的遍历。所以,如果你想共用这个模板,请确保你的Action函数中传入了paginator参数并且是分页器Pagerfanta对象。

回到动态列表页,显示正常,在搜索框中输入“内容”,回车,搜索结果页也成功显示了。 如果你想完整的实现分页功能,还需要在搜索Action中传入另两个参数,page用于当前的页码,limit当前列表项数量限制。 对paginator对象设置这两个参数

$page = $request->get('page', 1);
$limit = $request->get('limit', 10);

$paginator->setMaxPerPage($limit);
$paginator->setCurrentPage($page);

在搜索结果页面url中传入参数limit=1,搜索结果进行了分页,并成功显示了。

下一节,我们来完成边栏剩下的功能。

课程讨论

当前内容评论功能已关闭。