第一次使用drupal开发网站的时候,被卡在了内容页的输出环节。
按照白龙对官方文档的理解,用node.html.twig模板,结合content涉及的变量{{label}}、{{content.field_author_name}}、{{content.field_date}}、{{content.field_body}},就可以成功输出内容页的标题、作者、日期、正文等字段。但是,在node.html.twig对应的内容页面,当白龙使用page变量{{page.primary_menu}}调用page页面定制好的导航菜单、header、footer等区域内容时,失败了,无法正常显示!!说明{{page.primary_menu}}无法直接在node.html.twig模板正常输出。
根据内容页debug的SUGGESTIONS,白龙把内容页面模板名字改成了page--node--%.html.twig,重建缓存后,page--node--%.html.twig模板对应页面,定制的菜单导航{{page.primary_menu}}、{{page.header}}、{{page.footer}}等区域可以正常输出了,但是,内容页的字段又不显示了,这是什么原因呢?
基于以上2点,白龙总结了下,page--node--%.html.twig页面,可以正常输出定制的区域,但无法正常输出node.html.twig页面对应的字段。而单独的node.html.twig页面,可以正常输出对应字段,却无法正常输出page--node--%.html.twig模板定义的区域。
带上上述疑惑,通过查看官方文档说明,网上检索资料,很遗憾,可参考的教程几乎没有,仍然没有结果。一个偶然的机会,白龙在drupal7的一个文档中发现,内容页的输出是通过page--node--%.html.twig和node.html.twig两个模板协同工作来完成对应功能的。然后,白龙再次研读了这两个模板的官方说明,意外发现了这两个模板的共同之处,那就是:page.html.twig模板有content变量,可以通过{{page.content}}输出文章的所有字段。而node.html.twig也有一个content变量,可以通过{{content}}输出所有字段,或者通过{{content.field_name}}变量输出某一个字段。
基于以上分析,白龙意外的找到了两个模板的契合点,即,在page--node--%.html.twig模板中通过{{page.content}}来调用node.html.twig中的全部字段,或者部分字段。这样,就可以保证page--node--%.html.twig中定制的区域、node.html.twig模板中的部分或全部字段同时分别输出到2个模板。
整体思路搞清楚了,接下来,白龙用一个案例印证了上述猜想。
一、把内容页article.html转换成page--node--%.html.twig,并放入templates目录下;同时新建node.html.twig模板。
1.复制article.html到article.html目录下,并把其名子修改为page--node--%.html.twig;
2.去掉body(包括body本身)以外的所有代码;
3.引入CSS/JS,并修改images路径;
4.新建node.html.twig模板。
二、在page--node--%.html.twig中找到要输出文章(或者内容)的代码,用{{page.content}}替代。
三、把{{page.content}}代替的内容剪切到templates\node.html.twig模板,并分别用对应变量label、{{content.field_date}}、{{content.field_body}}替代标题、时间、正文。
四、重建缓存,刷新内容页,文章(标题、日期、正文)按照指定格式输出。
同时,大家可以注意下上图,在内容页中,使用page--node--%.html.twig模板定制的导航菜单也可以正常输出了。这就实现了通过page与node模板协同工作,同时输出定制的区域和文章内容。
值得注意的是,page--node--%.html.twig、node.html.twig是通用模板,即所有内容页显示为一个相同的内容页。如果有特殊内容页需求,譬如内容类型A的内容页与其它内容页样式不一样,则可以使用page--node--A.html.twig、node--A.html.twig模板,结合上面分享的方法来实现。