Представления встроенного контроллера с активами - PullRequest
1 голос
/ 11 февраля 2012

В настоящее время я работаю над приложением symfony2 и использую встроенные контроллеры. Мои встроенные контроллеры похожи на виджеты, которые должны инкапсулировать свой собственный набор функций и могут быть встроены в любом месте, и все же они должны функционировать.

У меня есть контроллер, называемый пользователями в сети. Представление, которое это генерирует, просто, просто список пользователей онлайн. Но я хотел бы добавить в это представление некоторый javascript, чтобы я мог использовать ajax для получения информации о пользователе, на которого нажали.

Контроллер в основном возвращает представление:

return $this->render('AppBundle:Users:usersOnline.html.twig', array('somedata' => $data);

Вот вид для этого контроллера:

{% extends partial.html.twig" %}
{%  block content %}
 <ul>
   <li><a href="site.com/ajax/user/1">User 1</a></li> (this would all be generated using 'somedata')
   <li><a href="site.com/ajax/user/2">User 2</a></li>
   ....
 <ul>
{% endblock content %}
{%  block scripts %}
   ..some javascript for interacting with this widget
{% endblock %}

Это часть, которая расширена с:

{%  block content %}
{% endblock content %}

{%  block scripts %}{% endblock %}

Вот главная страница, в которую встроен контроллер:

{% "base.html.twig" %}
{% block title %}Main{% endblock %}

{% block content %}
 ..some markup here
 <div id="usersonline">
  {% render "AppBundle:Users:usersOnline" with {'max': 4} %}
 </div>
{% endblock %}

{% block scripts %}
  ..some javascript
{% endblock %}

Это база, на которую он распространяется:

<!DOCTYPE html>
<html>
    <head>
     <meta charset="utf-8">
     <title>{% block title %}{% endblock %} - App</title>       
     ...Some stylesheets
    </head>
    <body>
        {% block content %}{% endblock %}
        <script src="http://yui.yahooapis.com/3.5.0pr2/build/yui/yui-min.js"></script>
        {%  block scripts %}{% endblock %}
    </body>
</html>

Проблема, с которой я сейчас сталкиваюсь, заключается в включении javascript-кодов со встроенного контроллера. В моем случае представление расширяется частично и полностью отображается как 1 единица, прежде чем оно будет вставлено на главную страницу. В этом случае я могу только поместить свой javascript в блок content, что означает, что у меня будут теги <script> в тегах <div>. Я также предпочел бы иметь скрипты в конце тела для производительности пользовательского интерфейса.

Как мне структурировать свои шаблоны (или это вообще возможно), чтобы я мог рендерить соответствующие фрагменты из представления встроенного контроллера в соответствующие блоки в шаблоне, в который встроен контроллер? В моем текущем шаблоне библиотека YUI будет загружена после рендеринга HTML-кода встроенного контроллера, поэтому доступ к библиотеке YUI во встроенном контроллере будет невозможен.

Ответы [ 2 ]

0 голосов
/ 08 марта 2013

После одного дня поиска удовлетворительного решения я, наконец, выбрал следующий подход:

  • Визуализация контроллера для функциональности вашего виджета (как вы уже делаете);
  • Рендеринг шаблонов для встраивания ресурсов вашего виджета (контроллеры не нужны и будут терять вашу производительность). Игнорировать, если шаблон не существует.
  • Используйте согласованное соглашение об именах, чтобы сделать функциональность виджета более динамичной.

Пример для одного виджета:

{% "base.html.twig" %}
{% block title %}Main{% endblock %}

{% block content %}
 ..some markup here
 <div id="usersonline">
  {{ render(controller("AppBundle:Users:usersOnline", {'max': 4})) }}
 </div>
{% endblock %}

{% block scripts %}
  {{ include("AppBundle:Users:usersOnline_js.html.twig" ignore missing }}
{% endblock %}

{% block stylesheets %}
  {{ include("AppBundle:Users:usersOnline_css.html.twig" ignore missing }}
{% endblock %}

(Как видите, я использую Symfony 2.2 для включения и встраивания)

Или более динамичный способ рендеринга виджетов:

{% "base.html.twig" %}
{% block title %}Main{% endblock %}

{% block widgets %}
 ..some markup here
  {% for widget in widgets %}
    {{ render(controller(widget.controller ~ ':widget', widget.options)) }}
  {% endfor %}
{% endblock %}

{% block scripts %}
  {% for widget in widgets %}
    {{ include(widget.controller ~ ':widget_js.html.twig' ignore missing }}
  {% endfor %}
{% endblock %}

{% block stylesheets %}
  {% for widget in widgets %}
    {{ include(widget.controller ~ ':widget_css.html.twig' ignore missing }}
  {% endfor %}
{% endblock %}

Мой вывод

Рендеринг нескольких контроллеров на одной странице при «объединении» блоков шаблонов не может быть реализован «из коробки» в Symfony2. Symfony2 всегда фокусировался на одном контроллере для каждого запроса, что объясняет, почему выходы нескольких контроллеров разделены и их трудно объединить.

Я думаю, что Symfony CMF имеет (или будет иметь) правильное решение для этого, потому что вся эта тема о виджетах больше применяется на веб-сайтах, управляемых динамическим контентом.

В любом случае, я думаю, что мой способ объединения встроенных контроллеров и включенных шаблонов - лучший подход для Symfony 2.

Альтернативы, на мой взгляд, имеют много недостатков:

  • Использование нескольких контроллеров: слишком тяжело и не нужно, потому что ресурсам не нужен контроллер.
  • Загрузка ресурсов виджетов непосредственно на странице: трудно поддерживать при изменении виджетов / активов.
0 голосов
/ 12 февраля 2012

Я написал расширение, которое по сути является парсером токенов, чтобы справиться с этим.Документация для анализатора токенов очень скудна, и код также в основном не комментируется, поэтому потребовалось немного возиться с работой.

Я структурировал синтаксический анализатор так, чтобы в начале вы могли что-то объявить(аналогично {% use %}):

{% myparser "AppBundle:Users:usersOnline" with {'max': 4} as xyz %}

Затем будут доступны блоки типа xyzcontent, а затем вы просто визуализируете их в соответствующих местах, используя {{block ('xyzcontent')}}.Это работает довольно хорошо.Однако следующее не работает:

{% set max = 4 %}
{% myparser "AppBundle:Users:usersOnline" with {'max': max} as xyz %}

Я не смог найти способ оценить выражение и получить его значение непосредственно в парсере токена.По большей части это работает нормально, за исключением этой проблемы.

Если кто-то имеет представление о том, как получить значение переменной в парсере токена, было бы здорово:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...