Transphporm-另一种模板引擎

If there is one thing the world needs, it’s definitely another PHP template engine! But wait, this one is different!

如果世界需要一件事,那么绝对是另一PHP模板引擎! 但是,等等,这是不同的!

Many PHP template engines (Smarty, Blade, Twig…) are little more than abstracted PHP code, making it easier to write loops, if/then/else blocks, and display variables with less verbosity than vanilla PHP. These traditional template engines require the designer to have an understanding of special syntax. The template engine must also be in place and operational in order to parse data and thus completely render the final design. Nothing wrong with this.

许多PHP模板引擎( SmartyBladeTwig …)只不过是抽象PHP代码,因此与普通PHP相比,更容易编写循环,if / then / else块,并以较低的详细程度显示变量。 这些传统的模板引擎要求设计人员对特殊语法有所了解。 模板引擎还必须就位并且可以运行,以便解析数据并因此完全呈现最终设计。 没错。

Magazine, flyer, brochure, cover layout design print template

Transphporm follows a different approach that is generally known as “template animation”. What this means is that the web designer creates the entire HTML/CSS/JS page including placeholder content such as “Lorem Ipsum”, then the template engine comes along and replaces parts of the DOM with new data before the final render.

Transphporm遵循一种不同的方法,通常称为“模板动画”。 这意味着Web设计人员将创建包括占位符内容(例如“ Lorem Ipsum”)的整个 HTML / CSS / JS页面,然后模板引擎随即出现,并在最终渲染之前用新数据替换DOM的一部分。

The benefit of template animation is that the designer does not have to know the backend code, template language, or any particular special syntax. They can use whatever tools they want to create 100% functional HTML pages.

模板动画的好处是设计人员不必知道后端代码,模板语言或任何特定的特殊语法。 他们可以使用想要创建100%功能性HTML页面的任何工具。

The server-side software does not even need to function while the designer works. This means the designer doesn’t have to wait for the backend to deliver data for them to work with.

在设计人员工作时,服务器端软件甚至不需要运行。 这意味着设计人员不必等待后端交付数据即可使用。

Basically, the designer can work with this:

基本上,设计人员可以使用以下方法:

<h1>A Good Title Here</h1>
<p>A subtitle</p>

<p>Some awesome text for clients to see.</p>

Instead of this:

代替这个:

<h1>{$futuretitle|upper}</h1>
<p>{$futuresubtitle|capitalize:true|default:'Default Text'}</p>

<p>{$futureawesometext}</p>

The placeholder content in the first example will be replaced by Transphporm. In the second example, the template engine must be functional and parsing the templates in order to see the final design as the designer envisions it.

第一个示例中的占位符内容将被Transphporm替换。 在第二个示例中,模板引擎必须能够正常工作并解析模板,以使最终设计符合设计人员的设想。

Notice how the separation of concerns reaches nearly 100%. There is no special syntax or code that the designer needs to know. On the server-side, Transphporm does not need to have any HTML tags hard-coded. You don’t have logic and code on the front end, and you don’t have presentation and nodes being hard-coded in the backend.

请注意关注点分离如何达到近100%。 设计人员不需要知道任何特殊的语法或代码。 在服务器端,Transphporm不需要硬编码任何HTML标记。 前端没有逻辑和代码,后端也没有硬编码的表示和节点。

Note: The backend may still produce reasonable HTML tags such as what is created through a WYSIWYG editor. i.e img, a, p, strong, em, etc., but never block level when done right.

注意:后端可能仍会生成合理HTML标记,例如通过WYSIWYG编辑器创建的标记。 即img,a,p,strong,em等,但正确完成后再也不会阻塞级别。

Let’s see how this works. If you’d like to follow along, please prepare a new environment.

让我们看看它是如何工作的。 如果您想继续,请准备一个新环境

安装Transphporm (Installing Transphporm)

In the public folder of our project, we’ll install the package via Composer.

在我们项目的public文件夹中,我们将通过Composer安装该软件包。

composer require level-2/transphporm:dev-master

Then, we create a new index.php file with the content:

然后,我们创建一个新的带有内容的index.php文件:

<?php

require 'vendor/autoload.php';

Note: Frequently run composer update as Transphporm is an active project. It updated a few times during the writing of this article.

注意:由于Transphporm是活动的项目,因此经常运行composer update 在撰写本文期间,它进行了几次更新。

创建页面 (Create Your Pages)

Transphporm requires no front-end syntax or special code at the design level. We will use a CSS-like selection language to find and replace content before rendering output to the browser.

Transphporm在设计级别不需要前端语法或特殊代码。 在将输出呈现到浏览器之前,我们将使用类似于CSS的选择语言来查找和替换内容。

By the nature of template animation I can theoretically grab any ready-to-go template off the web so long as it is XHTML valid. This means <meta charset='utf-8' /> and not <meta charset='utf-8'> as is with current HTML5. Modern practice is to not use self-closing tags, but to be XML-valid, we must. Note that your final render can be HTML5, but the templates you create for Transphporm must be XHTML. This is just the nature of using PHP’s XML methods.

通过模板动画的性质,理论上我可以从Web上获取任何现成的模板,只要它是XHTML有效的即可 。 这意味着<meta charset='utf-8' />而不是<meta charset='utf-8'> ,与当前HTML5一样。 现代实践是不使用自动关闭标签,而必须使用XML验证。 请注意, 最终的渲染可以是HTML5,但是为Transphporm创建的模板必须是XHTML。 这只是使用PHP的XML方法的本质。

A Transphporm object requires two values. One is valid XHTML markup which represents the designer’s template. It could be an entire page, or just snippets of XHTML to be used in the greater theme. The other is TSS (Transphporm Style Sheet) directives which contain the replacement logic.

Transphporm对象需要两个值。 一种是有效的XHTML标记,它表示设计者的模板。 它可以是整个页面,也可以是用于更大主题的XHTML片段。 另一个是包含替换逻辑的TSS(Transphporm样式表)指令。

Reference the github page for full documentation as I can be only so verbose within the length of this article.

请参考github页面以获取完整文档,因为在本文长度之内,我只能这么冗长。

Add this to the index.php file:

将此添加到index.php文件:

$page = 'home.xml';

$tss = 'home.tss';

$template = new \Transphporm\Builder($page, $tss);

echo $template->output()->body;

Now create the home.xml file with this basic XHTML template:

现在,使用以下基本XHTML模板创建home.xml文件:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        
        <title>HTML5 TEMPLATE</title>

        <style>
            body { padding: 20px; font-size:1em; }
            header nav { background-color:#ACEAD0; padding:15px 10px; }
            header nav ul { padding:0; }
            header nav li { display:inline; list-style:none; margin-right:15px; }
            header nav a { text-decoration:none; }
            article header h1 { margin-bottom:4px; color:#34769E; font-size:2em; }
            article header h2 { margin:0; font-size: .8em; color:#555; }
            article p { font-family:Arial, sans; color:#444; line-height:1.4em; }
            footer { background-color: #444; padding:10px; }
            footer p { color:#E2E2E2; }
        </style>

    </head>
  
    <body>
        <header>
            <nav>
                <ul>
                    <li><a href="#">Home</a></li>
                    <li><a href="#">The Goods</a></li>
                    <li><a href="#">Favorites</a></li>
                    <li><a href="#">Media</a></li>
                    <li><a href="#">Contact</a></li>
                </ul>
            </nav>
        </header>
        
        <main>
            <article>
                <header>
                    <h1>Page Title</h1>
                    <h2>By Jehoshaphat on Jan 1, 2015</h2>
                </header>
                
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut voluptas deserunt in quam itaque consequatur at recusandae, veritatis placeat porro cum magni eos iure vero, obcaecati est molestiae quos enim.</p>

                <p data-p="yes">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi sed asperiores cum explicabo praesentium, mollitia possimus nam. Aperiam autem doloribus hic. Ex quae quia fugiat, fugit eaque quam adipisci nemo.</p>
                
                <ul>
                  <li>A list item 1</li>
                </ul>
            </article>
        </main>
            
        <footer>
            <p>footer stuff</p>
        </footer>

    </body>
</html>

Now create a home.tss file with this:

现在使用以下home.tss创建一个home.tss文件:

article h1 {content: "My New Page Title"}

The TSS directive is “selecting” the h1 using CSS-like syntax. “Find an h1 that is a child of an article tag”. Note that specificity matters. If you had many article tags or many h1 tags, they would all be selected and changed!

TSS指令使用类似于CSS的语法“选择” h1。 “找到属于商品标签子项的h1”。 请注意,特异性很重要。 如果您有许多商品标签或许多h1标签,它们都将被选中并更改!

This is especially true for repeating nodes like the <li>. If there were more than one in our template, each individual list item would be replaced by the entire repeating dataset!

对于重复<li>类的节点尤其如此。 如果我们的模板中有多个,则每个单独的列表项都将被整个重复数据集替换!

If your index.php, home.xml, and home.tss files have been created correctly, you should be able to open the website and see the template. The template has <h1>Page Title</h1> but you should actually see “My New Page Title” when rendered in the browser.

如果正确创建了index.phphome.xmlhome.tss文件,则应该可以打开网站并查看模板。 该模板具有<h1>Page Title</h1>但是在浏览器中呈现该模板时,您实际上应该看到“我的新页面标题”。

Transphporm supports common CSS syntax including:

Transphporm支持常见CSS语法,包括:

  • .classname

    .classname

  • tagname.classname

    tagname.classname

  • direct > descendant

    direct > descendant

  • #id

    #id

  • element[attribute="value"] OR simply element[attribute]

    element[attribute="value"]或只是element[attribute]

Methods not supported include ~ and +.

不支持的方法包括~+

Beyond these selectors, Transphporm supports pseudo elements including:

除了这些选择器之外,Transphporm还支持伪元素,包括:

  • element:before

    element:before

  • element:after

    element:after

  • element:nth-child(n)

    element:nth-child(n)

  • element:even

    element:even

  • element:odd

    element:odd

You can chain selectors together just like in CSS.

您可以将选择器链接在一起,就像在CSS中一样。

article header > p {content: "First paragraph after the article header section"}

This is the easy stuff and is hopefully straightforward.

这是简单的事情,希望很简单。

At this point, you’re surely thinking “but I don’t want to hard code text in the TSS directive!”

此时,您肯定在思考“但我不想在TSS指令中对文本进行硬编码!”

Well, that’s where the fun begins.

好吧,这就是乐趣的开始。

处理数据 (Handling Data)

Let’s pretend this project is a bit more complicated. You are not likely to have the new <h1> content hard-coded in a TSS file! And you’ll likely have more than one piece of content to update.

让我们假装这个项目有点复杂。 您不太可能将新的<h1>内容硬编码到TSS文件中! 而且您可能将要更新多个内容。

I’m going to create an object called $data and assign some values to it.

我将创建一个名为$data的对象,并为其分配一些值。

Update index.php to this:

index.php更新为:

require 'vendor/autoload.php';

// Some fancy routing to setup the page.
$page = 'home.xml';
$tss  = 'home.tss';

// Some fancy controller/model action to get data.
$data = new stdClass;

$data->pagetitle = "Awesome Page";
$data->title     = "Article Title";
$data->subtitle  = "By Zack";

$template = new \Transphporm\Builder($page, $tss);

echo $template->output($data)->body;

Now we have $data as an object. We also added $data to the output() method.

现在我们将$data作为对象。 我们还将$data添加到output()方法。

The home.tss file can now be updated to this:

现在可以将home.tss文件更新为此:

title {content: data(pagetitle)}
article h1 {content: data(title)}
article h1 > h2 {content: data(subtitle)}

The attribute we use called content accepts a value called data(). This is similar to how in CSS you might supply rgba() as a value for color.

我们使用的名为content的属性接受一个名为data()的值。 这类似于在CSS中可能将rgba()作为color的值提供的方式。

At this point we can replace any content by utilizing the CSS syntax. Notice how we even replaced content within the <head> section.

此时,我们可以使用CSS语法替换任何内容。 注意我们甚至如何替换<head>部分中的内容。

DOM问题 (DOM Concerns)

At this point, you may be thinking that the designer and programmer don’t have to talk to each other; but on some level they do. The designer must use proper XHTML or the engine will crash (error handling may be improved over time).

在这一点上,您可能认为设计者和程序员不必互相交谈; 但在某种程度上,他们做到了。 设计人员必须使用正确的XHTML,否则引擎将崩溃(错误处理可能会随着时间的推移而得到改善)。

You might be wondering what happens if the designer changes the DOM and thus breaks a TSS selection. This can happen, especially if you rely more on the DOM tree than on well-thought-out IDs and classes. I would rather use id="posttitle" than rely on main article header > h1 which may not always be set in stone.

您可能想知道如果设计人员更改DOM从而中断TSS选择会发生什么。 这可能发生,尤其是如果您更多地依赖DOM树而不是经过深思熟虑的ID和类。 我宁愿使用id="posttitle"不是依赖main article header > h1 ,而main article header > h1可能并不总是固定在石头上。

多个局部 (Multiple Partials)

We can also utilize more than one XML file to assemble the final template.

我们还可以利用多个XML文件来组装最终模板。

Here is an example TSS file:

这是一个示例TSS文件:

@import 'another.tss';

aside {content: template("sidebar.xml")}

We can use @import to include other TSS files. We can also use template() to assign partial xml to the selected node as seen above. Any TSS directives that come after this line can affect the included xml file.

我们可以使用@import包含其他TSS文件。 我们还可以使用template()将部分xml分配给所选节点,如上所示。 此行之后的所有TSS指令都可能影响包含的xml文件。

This way, you can carefully craft the importing of xml partials and TSS directives to assemble the final page. Just like CSS, everything compiles top-down.

这样,您可以精心设计xml局部文件和TSS指令的导入,以组装最终页面。 就像CSS一样,所有内容都是自顶向下编译的。

Not only this, but you can replace content with partial content of the included template. In the above example, I’m including the entire sidebar.xml file. But what if I only want the <aside> within that file? Just do this:

不仅如此,您还可以用所包含模板的部分内容替换内容。 在上面的示例中,我包括了整个sidebar.xml文件。 但是,如果我只想要该文件中的<aside>怎么办? 只是这样做:

aside {content: template("sidebar.xml", "#extra aside")}

This will only pull the <aside> out from under the element with ID “extra”. The benefit of this is that the designer can still work with complete templates if they want to, even though you may only extract certain elements. It also means that, just as you can combine images together into a single file and use CSS to display them as needed, you can combine template elements in a single file and just extract the parts you need.

这只会从ID为“ extra”的元素下方拉出<aside> 。 这样做的好处是,即使您只提取某些元素,设计人员仍然可以使用完整的模板进行处理。 这也意味着,就像可以将图像组合到一个文件中并根据需要使用CSS来显示它们一样,您可以将模板元素组合在一个文件中,而只是提取所需的部分。

高级指令 (Advanced Directives)

One concern you might have is that if the designer breaks up the design into many partials, doesn’t that defeat the purpose of template animation because now you need Transphporm to put it back together? Kind of.

您可能会担心的一个问题是,如果设计师将设计分解为多个部分,这是否会破坏模板动画的目的,因为现在您需要Transphporm将其放回原处? 有点儿。

This is because the “master” template still contains the designer’s complete mockup. Nothing changes there. The “real” final markup will be within the partials. This makes the designer’s job only slightly more complex as they will have to edit the main design visually, then copy and change things within the partials for production. If they update the primary page, they may have to update partials too.

这是因为“主”模板仍包含设计者的完整模型。 那里什么都没有改变。 “真正的”最终标记将在部分中。 这使设计师的工作稍微复杂些,因为他们将不得不目视编辑主要设计,然后复制和更改零件中的内容以进行生产。 如果他们更新主页,他们可能也必须更新部分页面。

If you refer back to our basic HTML template, partials could easily be used for the header, the menu, the primary content area, the footer, etc. But placing these in partials doesn’t affect the designer being able to leave the primary base template fully intact and visually complete. The partials will simply replace the placeholder markup later.

如果回头看一下我们的基本HTML模板,则可以轻松地将partials用于页眉,菜单,主要内容区域,页脚等。但是将这些内容放在partials中不会影响设计者能够离开主要基础模板完整无缺,外观完整。 局部将稍后替换掉占位符标记。

And as we just saw, the partials themselves can be part of a larger complex or complete page.

正如我们刚刚看到的那样,部分页面本身可以是较大的复杂页面或完整页面的一部分。

重复资料 (Repeating Data)

Transphporm can handle repeat data through the use of a repeat() attribute.

Transphporm可以通过使用repeat()属性来处理重复数据。

Our template has an unordered list. We can fill it by using $data to pass an array of objects. Let’s add an array of fruit objects to index.php.

我们的模板具有无序列表。 我们可以使用$data传递对象数组来填充它。 让我们向index.php添加一个水果对象数组。

$fruits = []; // Master array of all fruits

$fruit = new stdClass;
$fruit->name = 'Apple';

$fruits[] = $fruit;

$fruit = new stdClass;
$fruit->name = 'Pear';

$fruits[] = $fruit;

$data->fruits = $fruits;

Now in the TSS file:

现在在TSS文件中:

article ul li {repeat: data(fruits); content: iteration(name)}

If you’ve added the data to index.php and updated the TSS file, the unordered list should now have two <li> nodes listing “Apple” and “Pear”.

如果已将数据添加到index.php并更新了TSS文件,则无序列表现在应具有两个<li>节点,分别列出“ Apple”和“ Pear”。

Before:

之前:

<ul>
    <li>A list item 1</li>
</ul>

After:

后:

<ul>
    <li>Apple</li>
    <li>Pear</li>
</ul>

Notice how we used two attributes “repeat” and “content” separated by a semicolon. Just like setting height, width, color and border in CSS on a single node, you can apply multiple transforms using a single selection with Transphporm.

注意,我们如何使用以分号分隔的两个属性“ repeat”和“ content”。 就像在单个节点上CSS中设置高度,宽度,颜色和边框一样,您可以使用Transphporm的单个选择来应用多个变换。

We passed data(fruits) to the repeat function. This will repeat the selected node (the <li>) including its closing tag. Then, we use iteration() to tell it what data within each fruit object to display.

我们将data(fruits)传递给repeat函数。 这将重复选择的节点( <li> ),包括其结束标记。 然后,我们使用iteration()告诉它要显示每个水果对象中的哪些数据。

Note: beside data() and iteration(), there are other transforms available including format which accepts the values “uppercase”, “lowercase”, “titlecase”, “date”, and can deal with numbers as well.

注:旁边的data()iteration()有可包括其他转换format ,它接受的价值观“大写”,“小写”,“首字母大写”,“日期”,并能处理数字为好。

属性 (Attributes)

Transphporm can do some fun stuff with attributes.

Transphporm可以通过属性来做一些有趣的事情。

Let’s say we wanted to hide the <li> if it equals “Apple”. To do this, we can inspect the current iteration and select based on that.

假设我们要隐藏<li>如果它等于“ Apple”。 为此,我们可以检查当前迭代并基于此进行选择。

article ul li:iteration[name='Apple'] {display: none;}

Notice how it works like a psuedo element by using a colon after the <li> and in square brackets matching a name=value pair. Notice also that Transphporm can just as easily hide elements with the familiar CSS directive display:none (though with Transphporm, the elements are fully removed from the DOM, not just hidden).

通过在<li>并在与name=value对匹配的方括号中使用冒号,可以注意到它像伪元素一样如何工作。 还请注意,Transphporm可以使用熟悉CSS指令display:none轻松隐藏元素(尽管使用Transphporm时,元素已从DOM中完全删除,而不仅仅是隐藏了)。

In our template, the second paragraph has data-p="yes". Let’s hide it based on that value.

在我们的模板中,第二段具有data-p="yes" 。 让我们根据该值隐藏它。

article p[data-p="yes"] {display:none}

Notice how there is no colon after p here like before when using iteration, which is a Transphporm function. We are selecting with normal CSS attribute syntax which doesn’t use a colon.

请注意,在p后面没有冒号,就像使用iteration时一样,这是Transphporm函数。 我们选择的标准CSS属性语法不使用冒号。

You can also set the content of the attributes themselves. The example from the docs uses a “mailto” link like so:

您还可以设置属性本身的内容。 文档中的示例使用“ mailto”链接,如下所示:

a:attr(href) {content: "mailto:", iteration(email)}

Again, attr is a Transphporm function so the colon is used. Also notice “(href)” is a direct selection of the attribute itself, no value is used.

同样, attr是Transphporm函数,因此使用冒号。 另请注意,“(href)”是属性本身的直接选择,不使用任何值。

Something cool happens here – content is set to “mailto:” but then we use a comma and the iteration’s value. Transphporm will concatenate multiple values when using a comma, e.g.:

此处发生了一些很酷的事情-内容设置为“ mailto:”,但随后我们使用逗号和迭代的值。 使用逗号时,Transphporm将连接多个值,例如:

p {content: "This ", "is ", "really ", "long"}

So with the previous “mailto” example, a proper attribute href="mailto:someemail@example.com" will be assembled.

因此,使用前面的“ mailto”示例,将组装适当的属性href="mailto:someemail@example.com"

标头 (Headers)

Transphporm does not send headers. You will have to use normal PHP functions for that.

Transphporm不发送标头。 您将必须使用常规PHP函数。

The output() method returns an object with two attributes. One is body which contains the rendered HTML, the other is headers which is an array of headers.

output()方法返回一个具有两个属性的对象。 一个是包含呈现HTML的body ,另一个是headers ,它是标头数组。

The way to set a header is to select the <html> element and use the built-in pseudo element :header to set it.

设置标题的方法是选择<html>元素,然后使用内置的伪元素:header进行设置。

html:header[location] {content: "/another-url"}

To make use of headers set this way, you’ll have to read the array returned by Transphporm, take those values and set them with PHP’s header() function. Instructions for how to do this are in the docs.

要使用以这种方式设置的标头,您必须读取Transphporm返回的数组,获取这些值,然后使用PHP的header()函数进行设置。 文档中提供了有关如何执行此操作的说明。

有条件的变化 (Conditional Changes)

It is possible to change elements based on logic in other parts of the application. Let’s say your program has a function like this one:

可以根据应用程序其他部分的逻辑来更改元素。 假设您的程序具有如下功能:

class Security {
  public function LoggedIn() {
    // Some logic
    return false;
  }
}

$data = new Security; // Be sure to pass $data to the output() method as usual

Now you can read this value and determine the appropriate action:

现在,您可以读取此值并确定适当的操作:

#welcome:data[LoggedIn=""] {display:none}

This could be quite handy!

这可能很方便!

It should be noted that, with template animation, we usually start with a complete template with all features, then strip away parts that don’t belong. We would build the template with “logged in” features, then remove them from the DOM if not needed.

应该注意的是,对于模板动画,我们通常从具有所有功能的完整模板开始,然后去除不属于的部分。 我们将使用“已登录”功能构建模板,然后在不需要时将其从DOM中删除。

This is described as a “top down” approach, as opposed to “bottom up” where only minimal markup is present, and we add stuff as needed.

这被描述为“自上而下”的方法,而不是“自下而上”的方法,在“自下而上”中仅存在最小的标记,我们根据需要添加内容。

Both approaches work with Transphporm.

两种方法都可以与Transphporm一起使用。

分离显示和逻辑的好处 (Benefits of Decoupled Display and Logic)

An advantage of separating display logic from markup is that they become decoupled entirely. This means that any given XML doesn’t have to belong to any given TSS. In fact, some XML could be used with different TSS and some TSS could be used with any other XML.

将显示逻辑与标记分开的一个优点是它们完全脱钩了。 这意味着任何给定的XML都不必属于任何给定的TSS。 实际上,某些XML可以与不同的TSS一起使用,而某些TSS可以与任何其他XML一起使用。

One example of this is using TSS to repopulate forms. A single TSS could be used to repopulate any given form template. It would look like this:

这样的一个例子是使用TSS重新填充表格。 单个TSS可以用于重新填充任何给定的表单模板。 它看起来像这样:

form textarea {content: data(attr(name))}
form input[type="text"]:attr(value) {content: data(attr(name))}

The function attr(name) reads the “name” attribute of the selected element. If the “name” attribute of the textarea element were “comments”, then it compiles to:

函数attr(name)读取所选元素的“ name”属性。 如果textarea元素的“名称”属性为“注释”,则它将编译为:

form textarea {content: data(comments)}

data(comments) here is referencing the passed-in $data object we’ve already used before, but it would work just as well if $_POST itself were passed instead.

这里的data(comments)引用了我们之前已经使用过的传入的$data对象,但是如果传递$_POST本身,它将同样有效。

The second line in the above TSS is selecting all form input elements with a type of “text”. It is then specifically selecting the value attribute itself which is where you would put content when populating a form. The data is, again, coming from data(xyz) where “xyz” is the name attribute of the selected element. In turn, the name attribute will match the data coming in from $_POST or a $data object.

上面的TSS中的第二行正在选择所有类型为“文本”的表单输入元素。 然后专门选择value属性本身,这是您在填充表单时放置内容的位置。 数据再次来自data(xyz) ,其中“ xyz”是所选元素的name属性。 反过来, name属性将匹配来自$_POST$data对象的$data

The end result is that anywhere you need to repopulate a form, you could simply include one TSS file like so:

最终结果是,您需要在任何地方重新填充表单,都可以仅包含一个TSS文件,如下所示:

import 'form-populate.tss';

As an example of passing $_POST you might do this in your PHP:

作为传递$_POST的示例,您可以在PHP中执行以下操作:

$data->title = "Article Title";
$data->formData = $_POST;

Once $_POST has been passed in through $data, a binding feature can specifically link formData to all the TSS used under that form element.

一旦通过$data传递了$_POST ,绑定功能就可以将formData专门链接到该form元素下使用的所有TSS。

form {bind: data(formData)}
/* Now that formData is bound to form, it can be accessed directly */
form input:attr(value) {content: data(attr(name))}

Binding just means I can call data(key) rather than data(formData[key]) because the context of data() was changed to reference formData directly.

绑定只是意味着我可以调用data(key)而不是data(formData[key])因为data()的上下文formData直接更改为引用formData

语言独立 (Language Independence)

It should be noted that decoupling means any language can be used to process the TSS files without any change to the templates. The author has built a sister compiler in Javascript that is 100% compatible as far as TSS and XML templates go. Find it on Github at Transjsform.

应当注意,解耦意味着可以使用任何语言来处理TSS文件,而无需对模板进行任何更改。 作者使用Javascript构建了一个姐妹编译器,就TSS和XML模板而言,该编译器100%兼容。 在Transjsform的 Github上找到它。

挑战性 (Challenges)

Using template animation takes care of both the designer and the coder. The designer can create their templates and partials without any real concern for the backend or template engine. Only valid XHTML is needed. The programmer, on the other hand, only needs the ability to easily find the DOM elements which need their content replaced.

使用模板动画会同时影响设计人员和编码人员。 设计人员可以创建自己的模板和部分部件,而无需任何后端或模板引擎的实际关注。 只需要有效的XHTML。 另一方面,程序员只需要能够轻松找到需要替换其内容的DOM元素。

The programmer and designer will, however, need a planned-out file structure for where to place major and minor templates, partials and so forth.

但是,程序员和设计人员将需要计划外的文件结构,以便在其中放置主要和次要模板,部分等。

The person who is not quite taken care of yet is the editor/writer.

还没有得到足够照顾的人是编辑/作家。

It’s fine to have XHTML templates. It’s fine to have TSS logic somewhere. The data can come from a controller and be assembled into a single $data object. But where do the writers write?

拥有XHTML模板很好。 在某处具有TSS逻辑很好。 数据可以来自控制器,并且可以组合成单个$data对象。 但是作家在哪里写?

Obviously, some form of editorial interface is going to be required to connect a writer to a particular piece of content/TSS to update it. There is nothing contained in the template itself to inform the backend which nodes require content editing and which do not.

显然,将作家连接到特定内容/ TSS进行更新将需要某种形式的编辑界面。 模板本身不包含任何内容来通知后端哪些节点需要内容编辑,哪些不需要。

Some form of meta-data will be required to say “this paragraph needs custom data, but this one does not”. The programmer also needs to know which sections will be replaced by a partial. There may even be multiple versions of a partial depending on some other application logic.

将需要某种形式的元数据说“此段需要自定义数据,但此段不需要”。 程序员还需要知道哪些部分将被部分替换。 取决于某些其他应用程序逻辑,甚至可能有部分的多个版本。

Because of this, we can’t really claim that there is a 100% separation between designers and coders, as they still need some level of congruity regarding the overall structure of things.

因此,我们不能真正声称设计师和编码人员之间存在100%的分离,因为他们仍然需要在事物的整体结构上达到某种程度的一致性。

使编辑器学习TSS? (Make the Editor Learn TSS?)

One of the reasons for template animation is to prevent a designer from having to learn a template language or syntax. This is a pointless goal if you are just making a writer learn TSS syntax instead! It would likely be much easier for a designer to learn a template syntax than to teach a writer CSS syntax.

模板动画的原因之一是防止设计人员必须学习模板语言或语法。 如果您只是让编写者学习TSS语法,那么这是没有意义的目标! 对于设计师而言 ,学习模板语法比教作者CSS语法要容易得多。

If the designer is also the content editor, then they have to learn TSS anyway, so why not just learn an existing mature template language? If the editor doesn’t know CSS syntax, nothing will be intuitive for them.

如果设计者还是内容编辑者,那么他们仍然必须学习TSS,那么为什么不只学习现有的成熟模板语言呢? 如果编辑器不知道CSS语法,那么对于他们来说,什么都不是直观的。

Parts of TSS are for assembling the page, other parts for assigning copy. Editors further only need access to some of these transforms. Some transforms may be structural in nature while others content oriented.

TSS的一部分用于组装页面,其他部分用于分配副本。 编辑者还只需要访问其中一些转换。 有些转换本质上可能是结构性的,而另一些则是面向内容的。

A true separation of concerns here must include the editors as well as the programmer and designer. No existing CMS is going to be able to adopt Transphporm as-is. A complicated template could potentially contain hundreds of transformations with lots of various logic paths. The content editors need a WYSIWYG.

这里真正要关注的问题必须包括编辑者以及程序员和设计师。 现有的CMS都无法按原样采用Transphporm。 一个复杂的模板可能包含数百个具有许多不同逻辑路径的转换。 内容编辑器需要一个所见即所得。

All together, this presents an interesting challenge for making Transphporm usable for everyone.

总之,这对于使Transphporm对所有人可用都提出了一个有趣的挑战。

It should be noted that the author is currently working on a parser where an editor could submit Markdown as the content and Transphporm would parse it into HTML for the output. This feature should be added very soon and takes us a step closer to an editing interface.

应当指出,作者当前正在使用一个解析器,其中编辑器可以提交Markdown作为内容,而Transphporm会将其解析为HTML作为输出。 此功能应尽快添加,使我们更靠近编辑界面。

快取 (Caching)

Basic caching is being implemented as written about here. Without a cache, PHP currently has to traverse the XHTML and parse TSS for every page load. In its current iteration, this could create a performance issue when using Transphporm.

基本缓存正在按此处的描述实现 。 没有缓存,PHP当前必须遍历XHTML并为每个页面加载解析TSS。 在当前的迭代中,使用Transphporm可能会导致性能问题。

结论 (Conclusion)

Using CSS-like syntax to select DOM elements is a very fun concept. Designers may find relief from having to learn a new syntax, and they can mock up 100% complete designs with no worry about the backend. This also means one should be able to download any XHTML, ready-made templates and get started relatively quickly with minimal DOM changes.

使用类似CSS的语法来选择DOM元素是一个非常有趣的概念。 设计人员可能不必学习新的语法,因此可以模拟100%完整的设计而不必担心后端。 这也意味着人们应该能够下载任何现成的XHTML模板,并且只需最少的DOM更改就可以相对快速地开始使用。

It’ll be interesting to see how this project matures. The first CMS interface to be created to manage TSS transforms and content editing will be particularly interesting.

看到这个项目如何成熟将会很有趣。 创建用于管理TSS转换和内容编辑的第一个CMS界面将特别有趣。

If you don’t like the way regular template engines work, maybe Transphporm is more up your alley? Take a look and let us know!

如果您不喜欢常规模板引擎的工作方式,也许Transphporm更适合您? 看一看,让我们知道!

翻译自: https://www.sitepoint.com/transphporm-a-different-kind-of-template-engine/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值