你的模板策略是什么?

4

我正试图开发自己的小型框架。为此,我想学习一些模板技术。我知道模板是一个非常复杂的话题,但了解一些策略可能会有助于找到正确的答案。

如果您提到一个,请不要只是写“smarty”等。请简要介绍其背后的概念。

让我先谈谈一个想法:为了简化事情,我的模板文件只是包含HTML的PHP文件。模板可以包括其他模板。通过$ data变量将数据插入模板,该变量是包含模板所有数据的关联数组。

因此,在第一阶段,控制器执行某些操作并建立$ data数组。接下来,将包含适当的模板。

问题:模板可能不仅需要包括模板,还需要包括控制器。即显示面包屑或菜单(具有相当复杂的逻辑,无法在模板中处理)。


相关且值得阅读:https://dev59.com/eUnSa4cB1Zd3GeqPNFqf - KiNgMaR
5个回答

3

我非常喜欢zend-framework对此的处理方式,并在我们的框架中使用它。 您将拥有一个视图类,其中将包含以下内容:

$view = new View();
$view->setTemplatesPath('.....');
$view->assign('name','value');
$view->render('index');

render方法将获取所有存储的变量并将它们作为属性包含在基于路径设置的模板中,因此在您的模板中,您将拥有:

<?php echo $this->foo; ?>
....
<?php echo $this->load('header'); // this includes another template ?>

1
他已经以类似的方式在做那件事了,他想要的与此无关。 - Alix Axel

3

0

这正是我处理的方式,视图中不会调用控制器(什么?!),我只是在首次调用视图的控制器中计算视图所需的所有必要数据。

视图永远不应该调用控制器/模型! 但是,如果你一定要这样做,可以尝试以下方式:

function Controller($pathToControler) // instantiates and returns the Controller
function Model($pathToModel) // instantiates and returns the Model

这样,在您的视图中,您可以像这样做:

$this->Controller('path/to/blog/tags.php')->List();

再次强调,你不应该使用这种模式,我只是提供解决方案,而不是鼓励使用。

同样地,你也可以在一个视图中调用另一个视图,像这样:

$this->View('path/to/views/header.php', array('title' => 'Hello World!'));

2
只要视图不改变模型的状态,它就可以调用模型,这没有任何问题。同样地,您也可以从视图调用控制器,例如,聚合来自多个控制器操作的输出,从而促进代码的重复使用。 - Gordon
@Gordon:是的,当然。但这不是MVC模式应该运行的方式。 - Alix Axel
1
嗯,声称MVC从来没有旨在以那种方式运行有点奇怪,因为它从一开始就没有考虑到网络。该模式可以追溯到1979年。如果说有什么不同的做法,那么今天人们使用MVC的方式绝对不是原本的意图。整个过程从浏览器通过HTTP传输到FrontController再到Controller再到Model,最后回到创建并设置全新视图的Controller(而不是模型通知视图其更改并更新自身),这些都不是原始MVC概念的一部分。 - Gordon
我不理解为什么会有负评,但这是的看法:视图顾名思义应该呈现来自模型的输出,而控制器则应该获取输入并在模型上处理它。你基本上在说视图可以做控制器的工作,而且直接调用模型也没关系;所以我问,为什么要用MVCMV似乎也能胜任这个工作,既然如此,我们干脆放弃一切,只坚持使用V好了。 - Alix Axel
不,我并没有说将请求处理放入V中,也没有说将M逻辑放入V中。我说的是如果需要呈现M,则可以从V中调用M和C,这样做不会违反关注点分离原则,也不会创建额外的依赖关系。这就是整个重点。 - Gordon

0

我的策略如下:

  1. 尽量减少在模板中使用 PHP,如果可能的话,甚至不用。
  2. 我已经为常见的网页组件创建了类,其中之一是tpanel,我将在下面演示这个概念。
  3. 例如,tpanel 将处理创建菜单的所有逻辑,解析一个名为“navigation_menu”的小模板,并将结果发送到整体模板中进行最终包含。

实际上,我正在创建“块”,这与 Drupal 所做的非常相似 - 如果您熟悉它的话。

        $this->load->library('tpanel');
        $s=$this->tpanel->get('date',$data);
        $s.=$this->tpanel->get('navigation_menu',$data);
        $s.=$this->tpanel->get('ajax_menu',$data);
        $s.=$this->tpanel->get('spacer',$data);
        $data['title']='List of Databases';
        $post=$this->uri->segment(5);
        $blog=(file_get_contents('../'.$dir.'/'.$post.'.dat'));
        $s.=markdown($blog);
        $data['content']=$s;
        $view='/admin/admin_simple_view';

系统比我上面展示的要灵活得多。例如,tpanel->get('ajax_menu, $data) 还使用jQuery处理脚本设置。
我最近也一直在研究Django,他们在模板方面有一些非常好的想法。即使你不是Python程序员,也值得一看,特别是他们如何处理继承。

0

这与你的问题并不直接相关,但是你考虑过客户端模板吗?John Resig在Javascript中有一个不错的micro-template,它可以配合Web服务和其他Ajax技术使用。获取或提交模板非常简单,然后再进行另一次获取或提交以获取数据。非常方便。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接