Статьи

Интеграция Polymer / Dart и Symfony — Часть 1

Мои первые четыре статьи для SitePoint посвящены Symfony (мой любимый PHP-фреймворк) и Dart (мой любимый инструмент разработки HTML 5).

В этой серии из двух частей мы рассмотрим, как объединить эти два мощных инструмента, то есть запустить Dart (после компиляции в JavaScript) на веб-сайте Symfony, чтобы добавить динамику. Мы также обсудим обходной путь, позволяющий избежать доступа JSONP к данным с удаленного сервера, на котором пользователь не имеет прямого контроля, а вызываемый API RESTful не имеет включенного CORS . Наконец, мы выделим ограничения интеграции и обратим внимание команды Dart, чтобы решить проблему и сделать Dart лучшей платформой.

Темы, обсуждаемые в этой статье, достаточно продвинуты. Читатели должны иметь общее представление о Symfony и Dart / Polymer. Под базовым пониманием я подразумеваю, что пользователь может самостоятельно разрабатывать сайт Symfony и приложение Dart и поэтому знаком с терминами, которые мы будем использовать в оставшейся части этой статьи. Читатель также должен понимать структуру веб-приложений Symfony и приложений Dart / Polymer. Чтобы узнать больше о Dart / Polymer, смотрите здесь , а о Symfony — мои предыдущие статьи .

Коды Dart / Polymer, используемые в этой программе, были загружены на Github . Не стесняйтесь клонировать копию и поиграть. Однако код Symfony не включен, так как он слишком большой и включает в себя множество файлов, не относящихся к теме, которую мы рассматриваем в этой статье.

Давайте начнем с части 1.

Типичный шаблон Symfony Twig

Symfony по умолчанию использует шаблонизатор Twig (другой продукт того же автора). Давайте посмотрим на типичный шаблон Twig:

File: Resources/views/Default/index.html.twig 
 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta name="description" content=""> <meta name="author" content="TR@SOE"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <link rel="shortcut icon" href="/favicon.ico"> <link rel="stylesheet" type="text/css" href="/css/semantic.css"> <link rel="stylesheet" type="text/css" href="/css/rsywx.css"> <title>{%block title%}Welcome to my website!{%endblock%}</title> </head> <body id="home"> {% block content %} <div class="ui page grid overview segment"> <div class="sixteen wide column"> <div class="ui four column center aligned stackable divided grid"> <div class="equal height row"> <div class="column"> <div class="ui icon header"> <a href="{{path('book_list')}}"><i class="circular inverted book link icon"></i></a> Books </div> <p>Up to {{"now"|date('Ym-d')}}, I have {{bs.summary.bc|number_format(0,'.',',')}}books. <br><br>The newest book collected (on ({{bs.last.purchdate|date('Ym-d')}}) is by {{bs.last.author}}, title: <a href="{{path('book_detail', {'id':bs.last.id})}}">{{bs.last.title}}</a></p> </div> </div> </div> </div> </div> {%endblock%} {{ include ('trrsywxBundle:Default:footer.html.twig') }} </body> </html> 

Выше приведена краткая версия страницы моего пересмотренного сайта. Он полностью совместим с HTML5, со всеми необходимыми компонентами: метас, CSS-ссылки, Semantic-UI (да, я изменил свои предпочтения с Bootstrap на Semantic-UI) и содержимое.

Механизм Twig HTML — это {%...%} и {{...}} часть. Пожалуйста, обратите особое внимание на нотацию {{...}} . Мы увидим, как это повлияет на наш HTML-шаблон Dart / Polymer.

Типичный HTML-шаблон Dart / Polymer (после сборки в пабе)

На домашней странице моего нового веб-сайта я хочу интегрировать два динамических элемента: один для получения случайной квоты из моей базы данных (размещенной на одном сервере), а другой — для получения информации о погоде моей резиденции из двух источников (один на китайском и еще на английском). Каждый «виджет» будет иметь кнопку «Обновить». Для виджета цитаты он получит новую случайную цитату, а для виджета погоды — переключение между отображением информации на китайском и английском языках.

Первое приложение Dart, на которое мы смотрим, — QOTD (Цитата дня). Код находится здесь . Это очень простое приложение Dart, поэтому мы пропустим объяснение части Dart и сосредоточимся только на скомпилированной версии этого приложения.

В вашей Dart IDE (я использую редактор Dart на основе Eclipse, но PHPStorm и WebStorm также поддерживают Dart), выберите файл build.dart и в меню выберите «Tools | Pub Build». Сгенерированные файлы будут помещены в каталог build . В этом каталоге, наряду с другими вспомогательными файлами (пакетами, CSS, шрифтами, изображениями и т. Д.), Используемыми для приложения Dart, будет два файла. Одним из них является скомпилированная версия JavaScript наших файлов Dart (в моем примере это getqotd.html_bootstrap.dart.js ), а другим — файл HTML ( getqotd.html ).

Здесь мы собираемся интегрировать содержимое этого каталога build в мою установку Symfony. Для этого потребуется несколько шагов:

Прежде всего, скопируйте все вспомогательные файлы / каталоги ( кроме файла getqotd.html ) в web каталог проекта Symfony. Пожалуйста, не забудьте сохранить структуру каталогов. В конце концов, структура каталогов, показанная на скриншоте выше, является довольно традиционной настройкой для любого веб-сайта. Опытные пользователи могут копировать файлы и каталоги в другое место. Это выполнимо, но может потребовать дальнейшей настройки на последующих этапах.

Теперь в web каталоге проекта Symfony, помимо этих сгенерированных Symfony файлов / каталогов, у нас есть еще несколько файлов, которые создают основу для приложения Dart (или, в моем контексте, я бы скорее назвал его Dart Widget).

Затем вернитесь к файлу index.html.twig и внесите некоторые изменения, чтобы включить необходимые файлы, связанные с Dart. Изменения, которые нужно сделать, могут быть getqotd.html файла getqotd.html и я суммирую их ниже:

Включите 3 JS-файла из Dart в раздел HTML <head>...</head> . Есть 3 файла: shadow_dom.debug.js , custom-elements.debug.js и interop.js . ПРИМЕЧАНИЕ. В производственной среде не используйте отладочную версию первых двух файлов JS и замените их на shadow_dom.min.js и custom-elements.min.js соответственно.

Теперь раздел <head>...</head> выглядит следующим образом:

 <head> <script src="/packages/shadow_dom/shadow_dom.debug.js"></script> <script src="/packages/custom_element/custom-elements.debug.js"></script> <script src="/packages/browser/interop.js"></script> <meta charset="utf-8"> ... </head> 

Убедитесь, что ссылки CSS верны. Обычно это избыточно, но при двойной проверке никакого вреда нет.

getgetqotd.html_bootstrap.dart.js файл Bootstrap JS: getgetqotd.html_bootstrap.dart.js .

И раздел <head>...</head> выглядит так:

 <head> <script src="/packages/shadow_dom/shadow_dom.debug.js"></script> <script src="/packages/custom_element/custom-elements.debug.js"></script> <script src="/packages/browser/interop.js"></script> <meta charset="utf-8"> ... <script src="/getwidget.html_bootstrap.dart.js"></script> </head> 
  1. Включите объявление <polymer-element>...</polymer-element> в сегмент <body>...</body> в самом начале:
  <body id="home"> <polymer-element> <polymer-element name="qotd-tag"> <template> <div class="ui message"> <p>{%verbatim%}{{quote}}{%endverbatim%}<br> <small><em>{%verbatim%}{{source}}{%endverbatim%}</em></small>&nbsp;&nbsp;<i title="Refresh" class="refresh teal icon small link" on-click="{%verbatim%}{{getQuote}}{%endverbatim%}"></i></p> </div> </template> </polymer-element> ... 

Шаблон фактически извлечен из файла qotd.html в моем хранилище. В процессе публикации Дарт просто копирует содержимое qotd.html в окончательный вывод getqotd.html .

Обратите особое внимание на пару тегов {%verbatim%}...{%endverbatim%} . Это синтаксис шаблона Twig (не Dart), сообщающий движку Twig, что все, что находится между этими двумя тегами, должно выводиться дословно.

Если мы пропустим эти теги, произойдет ошибка во время выполнения. В Twig {{...}} используется для вывода переменной. Так что Twig будет обрабатывать, скажем, {{source}} как отображение значения переменной с именем source . Очевидно, что source — это переменная Dart, используемая в шаблоне Polymer, и мы никогда бы не определили ее в Symfony (или если бы мы это сделали, нам нужно изменить имя переменной либо в Symfony, либо в Dart, чтобы избежать ненужной ссылки на неправильную переменную). Таким образом, поскольку Twig очень строги в использовании необъявленных переменных, появляется сообщение об ошибке «Переменная« источник »не существует».

Мы можем обойти это ограничение, настроив наш движок Twig на использование другого набора разделителей (например, пар {$ ... } стиле Smarty или пар <%= ... %> стиле Ruby). Но это требует некоторой продвинутой настройки внутри Twig. Так что с более простым и простым способом мы пропустим это. Единственный недостаток — мы должны вводить больше букв. Заинтересованные стороны могут прочитать, как определить свои собственные разделители Twig для более подробной информации.

Наконец, вставьте пару qotd-tag пользовательских элементов ( qotd-tag ) везде, где вы хотите, чтобы эта информация отображалась:

  <div class="ten wide column"> <qotd-tag></qotd-tag> </div> 

Вуаля! Загрузите эту страницу на ваш веб-сервер, и мы увидим, что виджет QOTD работает правильно. Он отображает случайную цитату из базы данных каждый раз, когда загружается страница или нажимается кнопка «Обновить».

Это стало важной вехой в нашей интеграции Dart-Symfony.

Вывод

В этой части мы внедрили Dart Widget на наш сайт и объяснили некоторые возможные помехи между используемыми технологиями. Во второй части мы сделаем несколько более сложных реализаций.

Есть отзывы? Оставь это в комментариях!