My first four articles for SitePoint are devoted to Symfony (my favorite PHP framework) and Dart (my favorite HTML 5 development tool).

关于SitePoint的前四篇文章专门介绍Symfony(我最喜欢PHP框架)和Dart(我最喜欢HTML 5开发工具)。

In this 2-part series, we are going to look at how to integrate these two powerful tools together, i.e. to run Dart (after compiling to JavaScript) in a Symfony website to add some dynamics. We will also discuss the work-around to avoid JSONP to access data from a remote server where the user has no direct control and the RESTful API called has no CORS enabled. Finally, we will highlight the limitation of the integration and seek the attention of the Dart team to solve the issue and make Dart a better platform.

在这个由两部分组成的系列文章中,我们将研究如何将这两个功能强大的工具集成在一起,即在Symfony网站中运行Dart(在编译为JavaScript之后)以增加一些动态。 我们还将讨论避免JSONP从远程服务器访问数据的变通方法,在远程服务器上,用户没有直接控制权,而调用的RESTful API没有启用CORS 。 最后,我们将强调集成的局限性,并寻求Dart团队的关注以解决问题,并使Dart成为一个更好的平台。

The topics discussed in this article are quite advanced. Readers are required to have a basic understanding of both Symfony and Dart/Polymer. By basic understanding, I mean the user can develop a Symfony site and a Dart app on their own and thus is familiar with the terms we are going to use in the rest of this article. The reader should also understand the structures of both Symfony web applications and Dart/Polymer applications. To learn about Dart/Polymer, see here, and to get familiar with Symfony, see my previous articles.

本文讨论的主题非常先进。 要求读者对Symfony和Dart / Polymer有基本的了解。 通过基本理解 ,我的意思是用户可以自行开发一个Symfony网站和一个Dart应用程序,从而熟悉我们将在本文其余部分中使用的术语。 读者还应该了解Symfony Web应用程序和Dart / Polymer应用程序的结构。 要了解有关Dart / Polymer的信息,请参见此处 ;要熟悉Symfony,请参阅我以前的文章

The Dart/Polymer codes used in this program have been uploaded to Github. Feel free to clone a copy and play around. However, the Symfony code is not included as it is too big and involves a lot of files that are not relevant to the topic we are covering in this article.

该程序中使用的Dart / Polymer代码已上传到Github 。 随意克隆副本并玩转。 但是,不包括Symfony代码,因为它太大了,并且包含许多与本文中涉及的主题无关的文件。

Let's get started with part 1.


典型的Symfony Twig模板 (A typical Symfony Twig template)

Symfony by default uses Twig (another product from the same author) template engine. Let's take a look at a typical Twig template:

默认情况下,Symfony使用Twig (同一作者的另一产品)模板引擎。 让我们看一下典型的Twig模板:

File: Resources/views/Default/index.html.twig
<!DOCTYPE html>
<html lang="zh-CN">
        <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>

    <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>
                            <p>Up to {{"now"|date('Y-m-d')}}, I have {{bs.summary.bc|number_format(0,'.',',')}}books. <br><br>The newest book collected (on ({{bs.last.purchdate|date('Y-m-d')}}) is by {{bs.last.author}}, title: <a href="{{path('book_detail', {'id':bs.last.id})}}">{{bs.last.title}}</a></p>

    {{ include ('trrsywxBundle:Default:footer.html.twig') }}

The above is the concise version of my revised site's index page. It is fully HTML5 compliant, with all the necessary components: metas, CSS links, Semantic-UI (Yes, I changed my preference from Bootstrap to Semantic-UI) and the contents.

以上是我修改后的网站的索引页面的简明版本。 它完全符合HTML5,具有所有必需的组件:元,CSS链接,语义UI(是的,我将自己的偏好从Bootstrap更改为语义UI)和内容。

The Twig engine of the HTML is the {%...%} and {{...}} part. Please pay special attention to the {{...}} notation. We will see how it will interfere with our Dart/Polymer HTML template later.

HTML的Twig引擎是{%...%}{{...}}部分。 请特别注意{{...}}表示法。 稍后,我们将看到它如何干扰Dart / Polymer HTML模板。

一个典型的Dart / Polymer HTML模板(在发布后) (A typical Dart/Polymer HTML template (after pub build))

In my new website's homepage, I want to integrate two dynamic elements: one is to get a random quote from my database (hosted in the same server), and the other to get weather information of my residence from two sources (one in Chinese and another in English). Each "widget" will have a "Refresh" button. For the quote widget, it will fetch a new random quote and for the weather widget, it will switch between displaying Chinese information and English information.

在新网站的主页上,我希望集成两个动态元素:一个是从我的数据库(位于同一服务器上)获取随机报价,另一个是从两个来源(我的中文和中文)获取我住所的天气信息。另一个英文)。 每个“小部件”都有一个“刷新”按钮。 对于报价小部件,它将获取一个新的随机报价,对于天气小部件,它将在显示中文信息和英文信息之间切换。

The first Dart app we look at is the QOTD (Quote Of The Day). The code is located here. It is a very simple Dart app so we will skip the explanation of the Dart portion and focus on the compiled version of this app only.

我们关注的第一个Dart应用是QOTD(当日行情)。 代码位于此处 。 这是一个非常简单的Dart应用程序,因此我们将跳过Dart部分的说明,仅关注此应用程序的编译版本。

In your Dart IDE (I am using the Eclipse-based Dart Editor, but PHPStorm and WebStorm also have Dart support), select the build.dart file and from menu choose "Tools | Pub Build". The generated files will be placed inside the build directory. In that directory, alongside other supporting files (packages, CSS, fonts, images, etc) used for the Dart app, there will be two files. One is the compiled JavaScript version of our Dart files (in my example it is getqotd.html_bootstrap.dart.js) and the other is the HTML file (getqotd.html).

在DART IDE(我使用的是基于Eclipse的Dart编辑器,但PHPStorm和WebStorm也有Dart的支持),选择build.dart文件,并从菜单中选择“工具|酒吧构建”。 生成的文件将放置在build目录中。 在该目录中,与Dart应用程序使用的其他支持文件(包,CSS,字体,图像等)一起,还有两个文件。 一个是Dart文件的已编译JavaScript版本(在我的示例中是getqotd.html_bootstrap.dart.js ),另一个是HTML文件( getqotd.html )。


What we are going to do here is to integrate the contents of this build directory into my Symfony setup. To do so, a few steps will be necessary:

我们在这里要做的是将该build目录的内容集成到我的Symfony设置中。 为此,将需要一些步骤:

First of all, copy all the supporting files/directories (except the getqotd.html file) into Symfony project's web directory. Please make sure to preserve the directory structure. After all, the directory structure shown in the above screenshot is quite a traditional setup in any web site. Advanced users can choose to copy the files and directories into a different location. It is doable but may require further tuning in later steps.

首先,将所有支持的文件/目录( getqotd.html文件除外 )复制到Symfony项目的web目录中。 请确保保留目录结构。 毕竟,以上屏幕快照中显示的目录结构是任何网站中的传统设置。 高级用户可以选择将文件和目录复制到其他位置。 这是可行的,但可能需要在后续步骤中进行进一步调整。

Now in Symfony project's web directory, besides those Symfony generated files/directories, we have a few more files that establishes the foundation for a Dart app (or, in my context, I'd rather call it a Dart Widget).


Next, go back to the index.html.twig file, make some changes to include necessary Dart-related files. The changes to be made can actually be grabbed from the getqotd.html file and I summarize below:

接下来,返回index.html.twig文件,进行一些更改以包括必要的Dart相关文件。 实际上,可以从getqotd.html文件中获取要进行的更改,下面总结一下:

Include 3 JS files from Dart in the HTML <head>...</head> section. There 3 files are: shadow_dom.debug.js, custom-elements.debug.js, and interop.js. NOTE: In production environment, please don't use the debug version of the first two JS files and replace them with shadow_dom.min.js and custom-elements.min.js, respectively.

在HTML <head>...</head>部分中包含3个来自Dart的JS文件。 共有3个文件: shadow_dom.debug.jscustom-elements.debug.jsinterop.js注意:在生产环境中,请不要使用前两个JS文件的调试版本,而分别将它们替换为shadow_dom.min.jscustom-elements.min.js

Now the <head>...</head> section looks like this:

现在, <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">

Make sure CSS links are correct. Usually this is redundant but no harm in double checking.

确保CSS链接正确。 通常这是多余的,但对双重检查没有害处。

Bring in the Bootstrap JS file: getgetqotd.html_bootstrap.dart.js.

getgetqotd.html_bootstrap.dart.js Bootstrap JS文件: getgetqotd.html_bootstrap.dart.js

And the <head>...</head> section looks like this:


        <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>
  1. Include the <polymer-element>...</polymer-element> declaration in the <body>...</body> segment at the very beginning:


<body id="home">
        <polymer-element name="qotd-tag">
                <div class="ui message">
                        <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>

The template is actually extracted from qotd.html file in my repository. During the publishing process, Dart simply copies the contents in qotd.html into the final output of getqotd.html.

该模板实际上是从我的存储库中的qotd.html文件中提取的。 在发布过程中,Dart只是拷贝内容qotd.html到的最终输出getqotd.html

Pay special attention to the {%verbatim%}...{%endverbatim%} tag pair. This is a Twig template syntax (not Dart) telling Twig engine that everything between these two tags should be outputted verbatim.

要特别注意{%verbatim%}...{%endverbatim%}标签对。 这是Twig模板语法(不是Dart),告诉Twig引擎这两个标签之间的所有内容都应逐字输出。

If we skip these tags, there will be a run-time error. In Twig, {{...}} is used to output a variable. So Twig will treat, say {{source}} as displaying the value of a variable called source. Obviously, source is a Dart variable used in Polymer template and we never would define it in our Symfony (or if we did, we need to change the variable name either in Symfony or in Dart to avoid unnecessary referencing the wrong variable). Thus, as Twig is very strict in using undeclared variables, the error pops saying "Variable 'source' does not exist".

如果我们跳过这些标签,则会出现运行时错误。 在Twig中, {{...}}用于输出变量。 因此,Twig将{{source}}视为显示名为source的变量的值。 显然, source是在Polymer模板中使用的Dart变量,我们永远不会在Symfony中定义它(或者,如果这样做,我们需要在Symfony或Dart中更改变量名称,以避免不必要的错误引用变量)。 因此,由于Twig在使用未声明的变量时非常严格,因此错误提示“变量'source'不存在”。

We can get around of this limitation by configuring our Twig engine to use a different set of delimiters (like Smarty-styled {$ ... } pairs, or Ruby-styled <%= ... %> pairs). But that requires some advanced tweaking inside Twig. So with a more straightforward and simpler way on hand, we will skip this. The only drawback is we have to key in more letters. Interested parties can read how to define your own Twig delimiters for more details.

我们可以通过将Twig引擎配置为使用不同的定界符集(例如Smarty样式的{$ ... }对或Ruby样式的<%= ... %>对)来解决此限制。 但这需要在Twig内部进行一些高级调整。 因此,通过一种更直接,更简单的方法,我们将跳过此步骤。 唯一的缺点是我们必须输入更多字母。 有兴趣的人士可以阅读如何定义自己的Twig分隔符以获取更多详细信息。

Finally, insert the custom-element tag (qotd-tag) pair wherever you want that information to be displayed:

最后,在希望显示该信息的任何地方插入custom-element标签( qotd-tag )对:

<div class="ten wide column">

Voila! Load that page in your web server and we can see that the QOTD widget is working properly. It displays a random quote from the database every time the page loads or the "Refresh" button is clicked.

瞧! 将该页面加载到您的Web服务器中,我们可以看到QOTD小部件正在正常工作。 每次页面加载或单击“刷新”时,它将显示数据库中的随机报价。

This has marked a milestone in our Dart-Symfony integration.


结论 (Conclusion)

In this part, we implemented a Dart Widget into our website and explained some possible interferences between the used technologies. In part 2, we'll do some more advanced implementations.

在这一部分中,我们在网站上实现了Dart Widget,并说明了所使用技术之间可能存在的一些干扰。 在第2部分中,我们将做一些更高级的实现。

Have feedback? Leave it in the comments!

有意见吗? 留在评论中!

翻译自: https://www.sitepoint.com/integrating-polymerdart-symfony-part-1/


  • 0
  • 0
  • 0
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
钱包余额 0