twig:将变量从视图传递给控制器

时间:2013-06-26 14:41:18

标签: php templates twig

设定:

  • Twig 1.13.1
  • PHP 5.4.3

问题:

我的数据库中有10,000篇文章。我需要一种方法只允许在页面上显示X个故事。我知道我可以在调用模板之前限制控制器中的数字,但根据使用的模板,该数字会有所不同。我将有一个控制器来处理所有文章。我需要一种方法将数字从模板传递到控制器以限制数组。我不想删除所有10,000篇文章,然后使用twig“slice”filter / func。

我知道在django你可以使用下面的内容。这只会加载前3个故事。

{% get_latest_stories 3 sports as story_list %}
{% for story in story_list %}
    {{ story.title }}
{% endfor %}

这是我当前的文件。

控制器

<?php
$stories = news_stories::getStories("sports",5); //getStories(section,limit);
?>

<?=$twig->render("storyList.html", array('stories' => $stories))?>

查看/模板

{% for story in story_list %}
    {{ story.title }}
{% endfor %}

摘要

我想要一种方法将一个数字从模板传递给控制器​​,以便我可以限制从DB返回的行的大概

3 个答案:

答案 0 :(得分:5)

从逻辑上讲,视图无法将某些内容传递给控制器​​,因为视图正在堆栈末尾处理,而不是其他所有内容。

但是,你可以将一个函数传递给视图。您可能希望创建某种getViewStories函数,您可以从twig模板访问该函数。由于您已在控制器中使用此功能:

<?php
$stories = news_stories::getStories("sports",5); //getStories(section,limit);
?>

<?=$twig->render("storyList.html", array('stories' => $stories))?>

您需要做的就是改变一下,如下所示:

<?php
$function = new Twig_SimpleFunction('getViewStories', function (section, limit) {
    return news_stories::getStories(section,limit);
});
$twig->addFunction($function);
?>

<?=$twig->render("storyList.html")?>

现在,从模板内部,您可以调用此函数,如下所示:

{% set story_list = getViewStories('sports',5) %}

{% for story in story_list %}
    {{ story.title }}
{% endfor %}

并更改每个模板中的getViewStories参数。

虽然您可以使用切片过滤器,但我会建议您使用切片过滤器,因为它会导致不必要的长数据库调用。这是最优化的方法(我知道)。

答案 1 :(得分:0)

您想使用切片过滤器,我认为这应该适合您

http://twig.sensiolabs.org/doc/filters/slice.html

{% for story in story_list|slice(1,5) %}
    {{ story.title }}
{% endfor %}

应仅返回元素1 - >;然后5循环中断循环。你也可以这样做

{% for story in story_list|[start:5] %}
    {{ story.title }}
{% endfor %}

免责声明:我从未真正使用过twig,虽然这只是快速浏览其文档

答案 2 :(得分:0)

您可以从树枝模板中嵌入控制器(或渲染其他网址)。这意味着您可以为自己的网站设置main layout模板,并保持storyList.html模板非常简单 - 只需迭代故事及其可能需要的任何标记。

main layout中,您将为新闻报道呈现动作:

<div id="stories">
    {% render url('...') with { section: 'sports', limit: 5}, {'standalone': 'js'} %}
</div>

这种方式需要在您的网页上添加hindclude.js。检查这些docs。如果你也在使用symfony(你提到MVC而不是框架) - 甚至更好。向上滚动一下,看看嵌入式控制器。

否则,我认为这种方式主要使用ajax。