视图助手 (Tags)(View Helpers (Tags))

因为HTML标签的命名方式和很多标签属性,让书写HTML标签变成一项超级沉闷的工作。Phalcon提供 Phalcon\Tag 类来处理这些复杂而无趣的事情。

这个简单的指导不是一个完整的关于视图助手的文档,请查看 Phalcon\Tag 以获得视图助手的完整说明。

文档类型(Document Type of Content)

Phalcon 提供 Phalcon\Tag::setDoctype() 方法可以设置输出内容的文档类型。此类型设置可能被其他的tag方法影响。

常量对应的文档类型
HTML32HTML 3.2
HTML401_STRICTHTML 4.01 严格模式
HTML401_TRANSITIONALHTML 4.01 过渡模式
HTML401_FRAMESETHTML 4.01 Frameset
HTML5HTML 5
XHTML10_STRICTXHTML 1.0 严格模式
XHTML10_TRANSITIONALXHTML 1.0 过渡模式
XHTML10_FRAMESETXHTML 1.0 Frameset
XHTML11XHTML 1.1
XHTML20XHTML 2.0
XHTML5XHTML 5

设置文档类型:

  1. <?php
  2. use Phalcon\Tag;
  3. $this->tag->setDoctype(Tag::HTML401_STRICT);
  4. ?>

获取文档类型:

  1. <?= $this->tag->getDoctype() ?>
  2. <html>
  3. <!-- your HTML code -->
  4. </html>

如下的html代码将被生成:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  2. "http://www.w3.org/TR/html4/strict.dtd">
  3. <html>
  4. <!-- your HTML code -->
  5. </html>

Volt 语法:

  1. {{ get_doctype() }}
  2. <html>
  3. <!-- your HTML code -->
  4. </html>

生成链接(Generating Links)

每一个普通的web应用都需要生成超链接去让我们在不同的页面之间进行导航。我们可以使用如下的方法创建指向我们站内的超链接:

  1. <!-- for the default route -->
  2. <?= $this->tag->linkTo("products/search", "Search") ?>
  3. <!-- with CSS attributes -->
  4. <?= $this->tag->linkTo(["products/edit/10", "Edit", "class" => "edit-btn"]) ?>
  5. <!-- for a named route -->
  6. <?= $this->tag->linkTo([["for" => "show-product", "title" => 123, "name" => "carrots"], "Show"]) ?>

事实上,上例所有URL都是被 Phalcon\Mvc\Url 生成的。

使用Volt生成超链接的例子:

  1. <!-- for the default route -->
  2. {{ link_to("products/search", "Search") }}
  3. <!-- for a named route -->
  4. {{ link_to(["for": "show-product", "id": 123, "name": "carrots"], "Show") }}
  5. <!-- for a named route with a HTML class -->
  6. {{ link_to(["for": "show-product", "id": 123, "name": "carrots"], "Show", "class": "edit-btn") }}

创建表单(Creating Forms)

在Web应用中,表单是获取用户输入的重要工具,下面的例子显示了使用视图助手(tag)如何去生成一个简单的form表单。

  1. <!-- Sending the form by method POST -->
  2. <?= $this->tag->form("products/search") ?>
  3. <label for="q">Search:</label>
  4. <?= $this->tag->textField("q") ?>
  5. <?= $this->tag->submitButton("Search") ?>
  6. <?= $this->tag->endForm() ?>
  7. <!-- Specifying another method or attributes for the FORM tag -->
  8. <?= $this->tag->form(["products/search", "method" => "get"]); ?>
  9. <label for="q">Search:</label>
  10. <?= $this->tag->textField("q"); ?>
  11. <?= $this->tag->submitButton("Search"); ?>
  12. <?= $this->tag->endForm() ?>

以上代码会生成如下的html:

  1. <form action="/store/products/search/" method="get">
  2. <label for="q">Search:</label>
  3. <input type="text" id="q" value="" name="q" />
  4. <input type="submit" value="Search" />
  5. </form>

使用Volt生成表单:

  1. <!-- Specifying another method or attributes for the FORM tag -->
  2. {{ form("products/search", "method": "get") }}
  3. <label for="q">Search:</label>
  4. {{ text_field("q") }}
  5. {{ submit_button("Search") }}
  6. {{ endForm() }}

Phalcon也提供了 form builder 类去以面向对象的风格去生成这样的表单。

使用助手生成表单控件(Helpers to Generate Form Elements)

Phalcon 提供了一系列的方法去生成例如文本域(text),按钮(button)和其他的一些form表单元素。提供给所有方法(helper)的第一个参数都是需要创建的表单元素的名称(name属性)。当提交表单的时候,这个名称将被和form表单数据一起传输。在控制器中,你可以使用request对象 ($this->request) 的 getPost()getQuery() 方法结合之前定义的名字(name属性)来获取到这些值。

  1. <?php echo $this->tag->textField("username") ?>
  2. <?php echo $this->tag->textArea(
  3. [
  4. "comment",
  5. "This is the content of the text-area",
  6. "cols" => "6",
  7. "rows" => 20,
  8. ]
  9. ) ?>
  10. <?php echo $this->tag->passwordField(
  11. [
  12. "password",
  13. "size" => 30,
  14. ]
  15. ) ?>
  16. <?php echo $this->tag->hiddenField(
  17. [
  18. "parent_id",
  19. "value" => "5",
  20. ]
  21. ) ?>

Volt 的语法:

  1. {{ text_field("username") }}
  2. {{ text_area("comment", "This is the content", "cols": "6", "rows": 20) }}
  3. {{ password_field("password", "size": 30) }}
  4. {{ hidden_field("parent_id", "value": "5") }}

使用选择框(Making Select Boxes)

生成选择框(select)很简单,特别是当你已经把相关的数据存储在了PHP的关联数组中。生成select的方法是 Phalcon\Tag::select()Phalcon\Tag::selectStatic() 。方法 Phalcon\Tag::select()Phalcon\Mvc\Model 一起使用会更好。当然 Phalcon\Tag::selectStatic() 也可以和PHP的数组一起工作。

  1. <?php
  2. $products = Products::find("type = 'vegetables'");
  3. // Using data from a resultset
  4. echo $this->tag->select(
  5. [
  6. "productId",
  7. $products,
  8. "using" => [
  9. "id",
  10. "name",
  11. ]
  12. ]
  13. );
  14. // Using data from an array
  15. echo $this->tag->selectStatic(
  16. [
  17. "status",
  18. [
  19. "A" => "Active",
  20. "I" => "Inactive",
  21. ]
  22. ]
  23. );

以下HTML代码将会被生成:

  1. <select id="productId" name="productId">
  2. <option value="101">Tomato</option>
  3. <option value="102">Lettuce</option>
  4. <option value="103">Beans</option>
  5. </select>
  6. <select id="status" name="status">
  7. <option value="A">Active</option>
  8. <option value="I">Inactive</option>
  9. </select>

你可以添加一个空的选项(option)到被生成的HTML页面中:

  1. <?php
  2. $products = Products::find("type = 'vegetables'");
  3. // Creating a Select Tag with an empty option
  4. echo $this->tag->select(
  5. [
  6. "productId",
  7. $products,
  8. "using" => [
  9. "id",
  10. "name",
  11. ],
  12. "useEmpty" => true,
  13. ]
  14. );

生成的HTML如下:

  1. <select id="productId" name="productId">
  2. <option value="">Choose..</option>
  3. <option value="101">Tomato</option>
  4. <option value="102">Lettuce</option>
  5. <option value="103">Beans</option>
  6. </select>
  1. <?php
  2. $products = Products::find("type = 'vegetables'");
  3. // Creating a Select Tag with an empty option with default text
  4. echo $this->tag->select(
  5. [
  6. "productId",
  7. $products,
  8. "using" => [
  9. "id",
  10. "name",
  11. ],
  12. "useEmpty" => true,
  13. "emptyText" => "Please, choose one...",
  14. "emptyValue" => "@",
  15. ]
  16. );
  1. <select id="productId" name="productId">
  2. <option value="@">Please, choose one..</option>
  3. <option value="101">Tomato</option>
  4. <option value="102">Lettuce</option>
  5. <option value="103">Beans</option>
  6. </select>

以Volt的语法生成以上的select选择框

  1. {# Creating a Select Tag with an empty option with default text #}
  2. {{ select('productId', products, 'using': ['id', 'name'],
  3. 'useEmpty': true, 'emptyText': 'Please, choose one...', 'emptyValue': '@') }}

设置 HTML 属性(Assigning HTML attributes)

所有的方法的第一个参数可以是一个数组,这个数组包含了这个被生成的HTML元素额外的属性。

  1. <?php $this->tag->textField(
  2. [
  3. "price",
  4. "size" => 20,
  5. "maxlength" => 30,
  6. "placeholder" => "Enter a price",
  7. ]
  8. ) ?>

Volt语法:

  1. {{ text_field("price", "size": 20, "maxlength": 30, "placeholder": "Enter a price") }}

以下的HTML代码将被生成。

  1. <input type="text" name="price" id="price" size="20" maxlength="30"
  2. placeholder="Enter a price" />

设置助手的值(Setting Helper Values)

通过控制器(From Controllers)

使用MVC框架编程时的一个好习惯是给form元素在视图中设定一个明确的值。你可以直接使用 Phalcon\Tag::setDefault() 在控制器中设置这个值。这个方法为所有的视图助手的方法预先设定了一个值,如果任意一个视图助手方法有一个和此预设值相匹配的名字,这个值将会被使用,除非那个视图方法明确的指定了这个值。

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. class ProductsController extends Controller
  4. {
  5. public function indexAction()
  6. {
  7. $this->tag->setDefault("color", "Blue");
  8. }
  9. }

例如,在视图中一个选择框助手方法(select helper)匹配到了这个之前被预设的值”color”

  1. <?php
  2. echo $this->tag->selectStatic(
  3. [
  4. "color",
  5. [
  6. "Yellow" => "Yellow",
  7. "Blue" => "Blue",
  8. "Red" => "Red",
  9. ]
  10. ]
  11. );

当这个选择框被生成的时候,”Blue”将被默认选中。

  1. <select id="color" name="color">
  2. <option value="Yellow">Yellow</option>
  3. <option value="Blue" selected="selected">Blue</option>
  4. <option value="Red">Red</option>
  5. </select>

通过请求(From the Request)

Phalcon\Tag 助手有一个特性,它可以在用户请求的时候保持表单的值。这个特性让你在不损失任何输入数据的情况下显示一些确认信息。

直接设置值(Specifying values directly)

所有的表单方法都支持参数”value”。你可以直接设置一个明确的值给表单方法。当这个值被明确设定的时候,任何通过 setDefault() 或者通过 请求(request) 所设置的值将被直接忽略。

动态设置文档标题(Changing dynamically the Document Title)

Phalcon\Tag 类提供了一些方法,让我们可以在控制器中动态地设置HTML文档的标题(title)。

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. class PostsController extends Controller
  4. {
  5. public function initialize()
  6. {
  7. $this->tag->setTitle("Your Website");
  8. }
  9. public function indexAction()
  10. {
  11. $this->tag->prependTitle("Index of Posts - ");
  12. }
  13. }
  1. <html>
  2. <head>
  3. <?php echo $this->tag->getTitle(); ?>
  4. </head>
  5. <body>
  6. </body>
  7. </html>

以下的HTML代码将会被生成:

  1. <html>
  2. <head>
  3. <title>Index of Posts - Your Website</title>
  4. </head>
  5. <body>
  6. </body>
  7. </html>

静态内容助手(Static Content Helpers)

Phalcon\Tag 也提供一些其他的方法去生成一些其他的标签,例如脚本(script),超链接(link)或者图片(img)。它可以帮助你很快的生成一些你应用中的静态资源

图片(Images)

  1. <?php
  2. // Generate <img src="/your-app/img/hello.gif">
  3. echo $this->tag->image("img/hello.gif");
  4. // Generate <img alt="alternative text" src="/your-app/img/hello.gif">
  5. echo $this->tag->image(
  6. [
  7. "img/hello.gif",
  8. "alt" => "alternative text",
  9. ]
  10. );

Volt 语法:

  1. {# Generate <img src="/your-app/img/hello.gif"> #}
  2. {{ image("img/hello.gif") }}
  3. {# Generate <img alt="alternative text" src="/your-app/img/hello.gif"> #}
  4. {{ image("img/hello.gif", "alt": "alternative text") }}

样式表(Stylesheets)

  1. <?php
  2. // Generate <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Rosario" type="text/css">
  3. echo $this->tag->stylesheetLink("http://fonts.googleapis.com/css?family=Rosario", false);
  4. // Generate <link rel="stylesheet" href="/your-app/css/styles.css" type="text/css">
  5. echo $this->tag->stylesheetLink("css/styles.css");

Volt 语法:

  1. {# Generate <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Rosario" type="text/css"> #}
  2. {{ stylesheet_link("http://fonts.googleapis.com/css?family=Rosario", false) }}
  3. {# Generate <link rel="stylesheet" href="/your-app/css/styles.css" type="text/css"> #}
  4. {{ stylesheet_link("css/styles.css") }}

脚本(Javascript)

  1. <?php
  2. // Generate <script src="http://localhost/javascript/jquery.min.js" type="text/javascript"></script>
  3. echo $this->tag->javascriptInclude("http://localhost/javascript/jquery.min.js", false);
  4. // Generate <script src="/your-app/javascript/jquery.min.js" type="text/javascript"></script>
  5. echo $this->tag->javascriptInclude("javascript/jquery.min.js");

Volt 语法:

  1. {# Generate <script src="http://localhost/javascript/jquery.min.js" type="text/javascript"></script> #}
  2. {{ javascript_include("http://localhost/javascript/jquery.min.js", false) }}
  3. {# Generate <script src="/your-app/javascript/jquery.min.js" type="text/javascript"></script> #}
  4. {{ javascript_include("javascript/jquery.min.js") }}

HTML5 对象(HTML5 elements - generic HTML helper)

Phalcon 提供了一个通用的方法去生成任何HTML的元素。在这个方法中,需要开发者将有效的HTML元素标签传给此方法。

  1. <?php
  2. // Generate
  3. // <canvas id="canvas1" width="300" class="cnvclass">
  4. // This is my canvas
  5. // </canvas>
  6. echo $this->tag->tagHtml("canvas", ["id" => "canvas1", "width" => "300", "class" => "cnvclass"], false, true, true);
  7. echo "This is my canvas";
  8. echo $this->tag->tagHtmlClose("canvas");

Volt 语法:

  1. {# Generate
  2. <canvas id="canvas1" width="300" class="cnvclass">
  3. This is my canvas
  4. </canvas> #}
  5. {{ tag_html("canvas", ["id": "canvas1", width": "300", "class": "cnvclass"], false, true, true) }}
  6. This is my canvas
  7. {{ tag_html_close("canvas") }}

标签服务(Tag Service)

Phalcon\Tag 类可以通过 ‘tag’ 服务来使用,这意味着你可以在服务容器被加载的任何地方访问到它。

  1. <?php echo $this->tag->linkTo("pages/about", "About") ?>

在服务容器中我们可以很容易的添加一个新的组件去替换’tag’组件。

  1. <?php
  2. use Phalcon\Tag;
  3. class MyTags extends Tag
  4. {
  5. // ...
  6. // Create a new helper
  7. public static function myAmazingHelper($parameters)
  8. {
  9. // ...
  10. }
  11. // Override an existing method
  12. public static function textField($parameters)
  13. {
  14. // ...
  15. }
  16. }

然后改变’tag’标签的定义:

  1. <?php
  2. $di["tag"] = function () {
  3. return new MyTags();
  4. };

创建助手(Creating your own helpers)

你可以简单地创建你自己的方法。首先,在你的控制器和模型的同级目录下创建一个新的文件夹,给此文件夹起一个和它功能相关的名字。在这里,叫它”customhelpers”好了。接下来我们在此文件夹下创建一个新的文件命名为 MyTags.php 这时,我们有一个类似于 /app/customhelpers/MyTags.php 的结构,我们将扩展(extend) Phalcon\Tag 并且实现(implement)这个类。下面是一个自定义的助手(helper)类:

  1. <?php
  2. use Phalcon\Tag;
  3. class MyTags extends Tag
  4. {
  5. /**
  6. * Generates a widget to show a HTML5 audio tag
  7. *
  8. * @param array
  9. * @return string
  10. */
  11. public static function audioField($parameters)
  12. {
  13. // Converting parameters to array if it is not
  14. if (!is_array($parameters)) {
  15. $parameters = [$parameters];
  16. }
  17. // Determining attributes "id" and "name"
  18. if (!isset($parameters[0])) {
  19. $parameters[0] = $parameters["id"];
  20. }
  21. $id = $parameters[0];
  22. if (!isset($parameters["name"])) {
  23. $parameters["name"] = $id;
  24. } else {
  25. if (!$parameters["name"]) {
  26. $parameters["name"] = $id;
  27. }
  28. }
  29. // Determining widget value,
  30. // \Phalcon\Tag::setDefault() allows to set the widget value
  31. if (isset($parameters["value"])) {
  32. $value = $parameters["value"];
  33. unset($parameters["value"]);
  34. } else {
  35. $value = self::getValue($id);
  36. }
  37. // Generate the tag code
  38. $code = '<audio id="' . $id . '" value="' . $value . '" ';
  39. foreach ($parameters as $key => $attributeValue) {
  40. if (!is_integer($key)) {
  41. $code.= $key . '="' . $attributeValue . '" ';
  42. }
  43. }
  44. $code.=" />";
  45. return $code;
  46. }
  47. }

在我们创建了自定义的助手(helper)类之后,我们要在我们的public目录下的”index.php”中自动加载那个包含我们自定义助手类的目录。

  1. <?php
  2. use Phalcon\Loader;
  3. use Phalcon\Mvc\Application;
  4. use Phalcon\Di\FactoryDefault();
  5. use Phalcon\Exception as PhalconException;
  6. try {
  7. $loader = new Loader();
  8. $loader->registerDirs(
  9. [
  10. "../app/controllers",
  11. "../app/models",
  12. "../app/customhelpers", // Add the new helpers folder
  13. ]
  14. );
  15. $loader->register();
  16. $di = new FactoryDefault();
  17. // Assign our new tag a definition so we can call it
  18. $di->set(
  19. "MyTags",
  20. function () {
  21. return new MyTags();
  22. }
  23. );
  24. $application = new Application($di);
  25. $response = $application->handle();
  26. $response->send();
  27. } catch (PhalconException $e) {
  28. echo "PhalconException: ", $e->getMessage();
  29. }

现在,你就可以在你的视图中使用你的新助手类了。

  1. <body>
  2. <?php
  3. echo MyTags::audioField(
  4. [
  5. "name" => "test",
  6. "id" => "audio_test",
  7. "src" => "/path/to/audio.mp3",
  8. ]
  9. );
  10. ?>
  11. </body>

在下一节中,我们将讨论关于 Volt 的内容,它是PHP的一个速度很快的模板引擎,在 Phalcon\Tag 中你将得到更多关于视图助手的友好的提示。