<commit_before>Templating in practice : Link helpers
=====================================

Overview
--------

One of the common needs in templates is the automation of the URL generation, and the inclusion of local files regardless of the file structure. The link and image helpers, for instance, naturally replace the `<a>` and `<img>` tags and do all the tedious jobs for you. Their use is compulsory to enable routing and relative links affected by configuration.

Introduction
------------

The way to call an action with an URL has already been explained: put the module and action names after the front controller, then the parameters of the action either in the classic "GET" style or between `/`:

    http://myapp.example.com/index.php/article/read?title=Finance_in_France
    // is equivalent to
    http:/myapp.example.com/index.php/article/read/title/Finance_in_France
    
    // additionally, the following works if the routing is deactivated
    http://myapp.example.com/index.php?module=article&action=read&title=Finance_in_France

Imagine that you want to add a hyperlink to this page in a template. In PHP, you could be tempted to write:

    [php]
    <a href="/index.php/article/read?title=Finance_in_France">Finance in France</a>

This is a bad idea, because: 

* by writing `index.php`, you point to a particular environment (in this case, the production environment). All links must be environment-independent if you don't want to accidentally change environment while navigating
* if you later decide to change the **routing** policy (you can learn more about this feature in the [routing chapter](routing.txt)), and to display another format of URL, you would have to parse all of your template files and replace by hand the URLs already entered to URLs like:

          [php]
          <a href="/index.php/articles/europe/france/finance.html">Finance in France</a>

If you ever built a website, you know that these problems occur all the time.

The link helpers are there for you. They allow symfony to create URLs and hyperlinks to actions compliant to the routing policy, without any dependence on the environment.

Link helpers
------------

### Syntax

The `url_for()` helper returns an URL, the `link_to()` helper returns a hyperlink. You may never use the first one, but you will use `link_to()` a lot.

    [php]
    <?php echo url_for('article/read?title=Finance_in_France') ?>
    // will generate in HTML
    http://myapp.example.com/index.php/article/read/title/Finance_in_France
    
    <?php echo link_to('interesting article', 'article/read?title=Finance_in_France') ?>
    // will generate in HTML
    <a href="http://myapp.example.com/index.php/article/read/title/Finance_in_France" title="interesting article">interesting article</a>
    
Notice that the default routing rules transform all the `?`, `=` and `&` characters into `/`. Also note that the `link_to()` helper gives a bonus `title` attribute for the `<a>` tag, based on the content of the tag that is provided.

Enter in the link helper exactly the same URL as you would have written in a `<a href="...` tag, and it will transform it for you into a "smart" link according to the current routing policy. And when the customer decides to change some of the rules, just modify the `routing.yml` configuration file and the generated URL can now look like:

    [php]
    <a href="http://myapp.example.com/articles/europe/france/finance.html" title="interesting article">interesting article</a>

Link helpers are the key to a double way routing. Interpreting URLs is not a big deal, but generating them requires that all hyperlink tags pass by the same filter. That's why these helpers are compulsory as soon as you may use the routing feature. Make sure you take a look at the [routing chapter](routing.txt) to see how to change the shape of URLs, get rid of the controller name or add a '.html' to the generated URLs for more efficient caching and indexing.

### Linking an image

Adding a link to an image is as simple as combining two helpers:

    [php]
    <?php echo link_to(image_tag('read.gif'), 'article/read?title=Finance_in_France') ?>
    //will generate in html
    <a href="/article/read/title/Finance_in_France.html"><img src="/images/read.gif" alt="Read" /></a>

The `image_tag` helper is described later in this chapter.

### Using the rule instead of the module/action

If you had a look at the [routing chapter](routing.txt), you saw that the routing is defined by rules. The link helpers accept a rule name instead of a `module/action` pair if an `@` is written before. For instance, if the `routing.yml` file contains the rule:

    cart:
      url: /shopping_cart
      param: { module: shoppingCart, action: index }

Then you can write

    [php]
    <?php echo link_to('go to shopping cart', '@cart') ?>

instead of

    [php]
    <?php echo link_to('go to shopping cart', 'shoppingCart/index') ?>
    
There are pros and cons to this trick.  The advantages are:

* The routing is done much faster, since symfony doesn't have to browse all the rules to find the one that matches the link. In a page with a great number of routed hyperlinks, the boost will be noticeable if you use rules instead of `module/action`.
* Using the rule helps to abstract the logic behind an action. If the need to plug another action behind a given URL arises, then only the `routing.yml` file will need to be changed - all the `link_to()` calls will still work without intervention.
* The logic of the call is more apparent with a rule name. Even if your modules and actions have explicit names, it is often better to call "display_article_by_title" than "article/display".

On the other hand,

* If you write rules in your `link_to()`, you can not deactivate the routing anymore.
* Debugging an application becomes less self-evident since you always need to refer to the `routing.yml` file to discover which action is called by a link.

The best choice depends on the project. In the long run, it's up to you.

### Fake GET and `post` option

Sometimes, web developers tend to use GET requests to actually do a POST. For instance, consider the following URL:

    http://myapp.example.com/index.php/shopping_cart/add?id=100

This request will change the data contained in the application, so it should be considered as a POST. 

This URL can be bookmarked, cached and indexed by search engines. Imagine all the nasty things that might happen to the users or to the statistics of a website using this technique. 

Symfony provides a way to transform a call to a `link_to` helper into an actual post. Just write:

    [php]
    <?php echo link_to('go to shopping cart', 'shoppingCart/add?id=100', 'post=true') ?>
    // will generate in HTML
    <a onclick="f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();return false;" href="/shoppingCart/add/id/100.html">go to shopping cart</a>

This `<a>` tag has an `href` attribute, so browsers without javascript support will follow the link doing the default GET. But for those with javascript support, the click on the link will actually do a POST request to the same URL, thanks to a dynamically-generated form in the `onclick` behavior. 

It is a good habit to tag as POST the links that actually post data. Don't hesitate to use this possibility.

### Additional options

In addition to the `post` option, the `link_to` helper accepts two other options : `confirm` and `popup`.

    [php]
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure?') ?>
    // will generate in HTML
    <a onclick="return confirm('Are you sure?');" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'popup=true') ?>
    // will generate in HTML
    <a onclick="window.open(this.href);return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', Array('popup' => Array('Window title','width=310,height=400,left=320,top=0'))) ?>
    // will generate in HTML
    <a onclick="window.open(this.href,'Window title','width=310,height=400,left=320,top=0');return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>

The options can be combined:

    [php]
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? post=true') ?>
    // will generate in HTML
    <a onclick="if (confirm('Are you sure?')) { f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit(); };return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? popup=true') ?>
    // will generate in HTML
    <a onclick="if (confirm('Are you sure?')) { window.open(this.href); };return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>

### Forcing GET variables

According to your routing rules, variables passed as parameters to a `link_to()` are transformed into patterns. The default rule transforms `?key=value` into `/key/value`:

    [php]
    <?php echo link_to('interesting article', 'article/read?title=Finance_in_France') ?>
    // will generate in the URL
    http://myapp.example.com/index.php/article/read/title/Finance_in_France

But what if you actually need to keep the GET syntax, i.e. to output an url like:

    [php]
    http://myapp.example.com/index.php/article/read?title=Finance_in_France

You should then put the variables that have to be forced outside of the `url` parameter, in the `query_string` option:

    [php]
    <?php echo link_to('interesting article', 'article/read', array('query_string' => 'title=Finance_in_France')) ?>

button_to helper
----------------

When dealing with forms, you might want to use buttons instead of links. This is where the `button_to` helper enters:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100') ?>
    // will generate in HTML
    <input value="add to cart" type="button" onclick="document.location.href='/fo_dev.php/shoppingCart/add/id/100.html';" />

Note that, by default, this button will do a GET request. If you want to do a POST, add the related option:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100', 'post=true') ?>
    // will generate in HTML
    <form method="post" class="button_to" action="/fo_dev.php/shoppingCart/add/id/100.html"><input value="add to cart" type="submit" /></form>

Beware not to use the POST mode when in a form, since it adds a new `<form>` tag: you would end up with a form inside another, and the additional button would submit the first form.

As for `link_to`, the `confirm` and `popup` options can be added and combined:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? popup=true') ?>
    // will generate in HTML
    <input value="add to cart" type="button" onclick="if (confirm('Are you sure?')) {window.open('/fo_dev.php/shoppingCart/add/id/100.html');}" />

mail_to helper
-------------

The reason why symfony ships a `mail_to()` helper is that nowadays, email harvesting robots prowl about the web, and you can't display an email address on a website without becoming a spam victim within days.

This helper takes three parameters : the actual email address, the string that should be displayed and an array of options. If the third parameter is not set the email address is written non-crypted:

    [php]
    <?php echo mail_to('<EMAIL>', 'contact address') ?>
    // will generate in HTML
    <a href="mailto:<EMAIL>'>contact address</a>

If the flag is set to array('encode' => true) the displayed and pointed addresses are processed by a random decimal and hexadecimal entity encoder. This will probably not stop all address-harvesting spambots, but it will keep most of them away. Future versions of this helper will probably evolve as the harvesting techniques become more accurate.

    [php]
    <?php echo mail_to('<EMAIL>', 'contact address', array('encode' => true)) ?>
    // will generate in HTML something like
    <a href="&#109;&#x61;&#105;&#108;&#x74;&#x6f;&#58;&#x6d;&#121;&#x61;&#x64;&#x64;&#114;&#101;&#x73;&#115;&#64;&#x6d;&#x79;&#100;o&#x6d;&#97;&#105;&#110;&#46;&#x63;&#111;&#x6d;">&#x63;&#111;&#110;&#x74;&#x61;c&#x74;&#32;&#x61;d&#100;&#114;e&#115;&#x73;</a>

Image helper
------------

Considering that all your HTML pages are handled by actions, the `href` attribute is not a worry anymore. But what about all those tags having a `src` attribute? Symfony has image and javascript helpers that are faster to write and do most of the job themselves. 

In addition, future versions will support configuration for the default location of media files. This may prove helpful if you decided suddenly to host all of your project media files (css, js, pdf, jpg, gif, etc.) in a new server to increase performance.

To create an `<img>` tag:

    [php]
    <?php echo image_tag('test') ?>
    // will generate in HTML
    <img href="/images/test.png" alt="Test" />

By default, the image `test.png` will be looked for in the `/images/` directory of the web server (which is the `myproject/web/image/` directory of your file structure, unless you customized it). 

If you need to change the default file type or the default location, you can pass a more defined URL:

    [php]
    <?php echo image_tag('test.gif') ?>
    // will generate in HTML
    <img href="/images/test.gif" alt="Test" />
    
    <?php echo image_tag('/my_images/test.gif') ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" />

You can add a second argument to specify additional HTML attributes; this argument must be an array. 

    [php]
    <?php echo image_tag('/my_images/test.gif', array('class' => 'shortImage')) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" class="shortImage"/>

Don't bother to specify a `alt` attribute if your media file has an explicit name, since symfony will determine it for you.

To fix the size of an image, use the attribute `size`:

    [php]
    <?php echo image_tag('/my_images/test.gif', array('size' => '100x20')) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" width="100" height="20"/>

To keep the code readable and let you write templates fast, the options argument can use an abbreviated string syntax:

    [php]
    <?php echo image_tag('/my_images/test.gif', 'size=100x20 alt=My new car class=shortImage onclick=showNextImage(); ') ?>
    // is the same as
    <?php echo image_tag('/my_images/test.gif', array('size' => '100x20', 'alt' => 'My new car', 'class' => 'shortImage' , 'onclick' => 'showNextImage();') ) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="My new car" width="100" height="20" class="shortImage" onclick="showNextImage();" />

JavaScript helper
-----------------

To link to JavaScript files, you can omit the path and the suffix: 

    [php]
    <?php echo javascript_include_tag('myscript') ?>
    // will generate in HTML
    <script language="javascript" type="text/javascript" src="/js/myscript.js">

Once again, the default location can be overridden in a function call for quick needs, or redefined for the whole site in the configuration files for major changes.

If you read the whole documentation, you will see that symfony gives you three different ways to require an additional JavaScript file. You should use them with this order of preference:

* parameter definition in the `view.yml` file: Most of the time, the best solution
* `$this->getResponse()->addJavascript()` method call from the action: When the name of the files to include depend on calculations made in the action
* `javascript_include_tag()` helpers in the template: To include a JavaScript file at a given position inside a template and not in the head.

The last solution is rarely good; if you need it, check whether your code needs some refactoring (for instance write a JavaScript function call in the code and require the script inclusion in the head). However, you sometimes don't have the choice, for instance if you have to include traffic measure scripts at the end of your pages.

>**Note**: You may be looking for a `stylesheet_tag()` helper, but there is none. If you need to include a custom stylesheet, you should not do it in the template but rather in the view or in the action, as described in the [view configuration chapter](templating_configuration.txt). This way, the declaration appears in the `<head>` instead of in the `<body>`.

Absolute paths
--------------

The url and asset helpers generate relative paths by default. You can easily add an `absolute=true` parameter to force the output to absolute paths, for instance for inclusions of links in an email, a RSS feed, or an API response.

    [php]
    <?php echo url_for('module/action', true) ?>
    <?php echo link_to('my link', 'module/action', 'absolute=true') ?>
    <?php echo image_tag('test', 'absolute=true') ?>
    <?php echo javascript_include_tag('myscript', 'absolute=true') ?><commit_msg>doc: removed mention of the title attribute being set automatically in link helpers<commit_after>Templating in practice : Link helpers
=====================================

Overview
--------

One of the common needs in templates is the automation of the URL generation, and the inclusion of local files regardless of the file structure. The link and image helpers, for instance, naturally replace the `<a>` and `<img>` tags and do all the tedious jobs for you. Their use is compulsory to enable routing and relative links affected by configuration.

Introduction
------------

The way to call an action with an URL has already been explained: put the module and action names after the front controller, then the parameters of the action either in the classic "GET" style or between `/`:

    http://myapp.example.com/index.php/article/read?title=Finance_in_France
    // is equivalent to
    http:/myapp.example.com/index.php/article/read/title/Finance_in_France
    
    // additionally, the following works if the routing is deactivated
    http://myapp.example.com/index.php?module=article&action=read&title=Finance_in_France

Imagine that you want to add a hyperlink to this page in a template. In PHP, you could be tempted to write:

    [php]
    <a href="/index.php/article/read?title=Finance_in_France">Finance in France</a>

This is a bad idea, because: 

* by writing `index.php`, you point to a particular environment (in this case, the production environment). All links must be environment-independent if you don't want to accidentally change environment while navigating
* if you later decide to change the **routing** policy (you can learn more about this feature in the [routing chapter](routing.txt)), and to display another format of URL, you would have to parse all of your template files and replace by hand the URLs already entered to URLs like:

          [php]
          <a href="/index.php/articles/europe/france/finance.html">Finance in France</a>

If you ever built a website, you know that these problems occur all the time.

The link helpers are there for you. They allow symfony to create URLs and hyperlinks to actions compliant to the routing policy, without any dependence on the environment.

Link helpers
------------

### Syntax

The `url_for()` helper returns an URL, the `link_to()` helper returns a hyperlink. You may never use the first one, but you will use `link_to()` a lot.

    [php]
    <?php echo url_for('article/read?title=Finance_in_France') ?>
    // will generate in HTML
    http://myapp.example.com/index.php/article/read/title/Finance_in_France
    
    <?php echo link_to('interesting article', 'article/read?title=Finance_in_France') ?>
    // will generate in HTML
    <a href="http://myapp.example.com/index.php/article/read/title/Finance_in_France">interesting article</a>
    
Notice that the default routing rules transform all the `?`, `=` and `&` characters into `/`. 

Enter in the link helper exactly the same URL as you would have written in a `<a href="...` tag, and it will transform it for you into a "smart" link according to the current routing policy. And when the customer decides to change some of the rules, just modify the `routing.yml` configuration file and the generated URL can now look like:

    [php]
    <a href="http://myapp.example.com/articles/europe/france/finance.html">interesting article</a>

Link helpers are the key to a double way routing. Interpreting URLs is not a big deal, but generating them requires that all hyperlink tags pass by the same filter. That's why these helpers are compulsory as soon as you may use the routing feature. Make sure you take a look at the [routing chapter](routing.txt) to see how to change the shape of URLs, get rid of the controller name or add a '.html' to the generated URLs for more efficient caching and indexing.

### Linking an image

Adding a link to an image is as simple as combining two helpers:

    [php]
    <?php echo link_to(image_tag('read.gif'), 'article/read?title=Finance_in_France') ?>
    //will generate in html
    <a href="/article/read/title/Finance_in_France.html"><img src="/images/read.gif" alt="Read" /></a>

The `image_tag` helper is described later in this chapter.

### Using the rule instead of the module/action

If you had a look at the [routing chapter](routing.txt), you saw that the routing is defined by rules. The link helpers accept a rule name instead of a `module/action` pair if an `@` is written before. For instance, if the `routing.yml` file contains the rule:

    cart:
      url: /shopping_cart
      param: { module: shoppingCart, action: index }

Then you can write

    [php]
    <?php echo link_to('go to shopping cart', '@cart') ?>

instead of

    [php]
    <?php echo link_to('go to shopping cart', 'shoppingCart/index') ?>
    
There are pros and cons to this trick.  The advantages are:

* The routing is done much faster, since symfony doesn't have to browse all the rules to find the one that matches the link. In a page with a great number of routed hyperlinks, the boost will be noticeable if you use rules instead of `module/action`.
* Using the rule helps to abstract the logic behind an action. If the need to plug another action behind a given URL arises, then only the `routing.yml` file will need to be changed - all the `link_to()` calls will still work without intervention.
* The logic of the call is more apparent with a rule name. Even if your modules and actions have explicit names, it is often better to call "display_article_by_title" than "article/display".

On the other hand,

* If you write rules in your `link_to()`, you can not deactivate the routing anymore.
* Debugging an application becomes less self-evident since you always need to refer to the `routing.yml` file to discover which action is called by a link.

The best choice depends on the project. In the long run, it's up to you.

### Fake GET and `post` option

Sometimes, web developers tend to use GET requests to actually do a POST. For instance, consider the following URL:

    http://myapp.example.com/index.php/shopping_cart/add?id=100

This request will change the data contained in the application, so it should be considered as a POST. 

This URL can be bookmarked, cached and indexed by search engines. Imagine all the nasty things that might happen to the users or to the statistics of a website using this technique. 

Symfony provides a way to transform a call to a `link_to` helper into an actual post. Just write:

    [php]
    <?php echo link_to('go to shopping cart', 'shoppingCart/add?id=100', 'post=true') ?>
    // will generate in HTML
    <a onclick="f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();return false;" href="/shoppingCart/add/id/100.html">go to shopping cart</a>

This `<a>` tag has an `href` attribute, so browsers without javascript support will follow the link doing the default GET. But for those with javascript support, the click on the link will actually do a POST request to the same URL, thanks to a dynamically-generated form in the `onclick` behavior. 

It is a good habit to tag as POST the links that actually post data. Don't hesitate to use this possibility.

### Additional options

In addition to the `post` option, the `link_to` helper accepts two other options : `confirm` and `popup`.

    [php]
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure?') ?>
    // will generate in HTML
    <a onclick="return confirm('Are you sure?');" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'popup=true') ?>
    // will generate in HTML
    <a onclick="window.open(this.href);return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', Array('popup' => Array('Window title','width=310,height=400,left=320,top=0'))) ?>
    // will generate in HTML
    <a onclick="window.open(this.href,'Window title','width=310,height=400,left=320,top=0');return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>

The options can be combined:

    [php]
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? post=true') ?>
    // will generate in HTML
    <a onclick="if (confirm('Are you sure?')) { f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit(); };return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>
    
    <?php echo link_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? popup=true') ?>
    // will generate in HTML
    <a onclick="if (confirm('Are you sure?')) { window.open(this.href); };return false;" href="/fo_dev.php/shoppingCart/add/id/100.html">add to cart</a>

### Forcing GET variables

According to your routing rules, variables passed as parameters to a `link_to()` are transformed into patterns. The default rule transforms `?key=value` into `/key/value`:

    [php]
    <?php echo link_to('interesting article', 'article/read?title=Finance_in_France') ?>
    // will generate in the URL
    http://myapp.example.com/index.php/article/read/title/Finance_in_France

But what if you actually need to keep the GET syntax, i.e. to output an url like:

    [php]
    http://myapp.example.com/index.php/article/read?title=Finance_in_France

You should then put the variables that have to be forced outside of the `url` parameter, in the `query_string` option:

    [php]
    <?php echo link_to('interesting article', 'article/read', array('query_string' => 'title=Finance_in_France')) ?>

button_to helper
----------------

When dealing with forms, you might want to use buttons instead of links. This is where the `button_to` helper enters:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100') ?>
    // will generate in HTML
    <input value="add to cart" type="button" onclick="document.location.href='/fo_dev.php/shoppingCart/add/id/100.html';" />

Note that, by default, this button will do a GET request. If you want to do a POST, add the related option:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100', 'post=true') ?>
    // will generate in HTML
    <form method="post" class="button_to" action="/fo_dev.php/shoppingCart/add/id/100.html"><input value="add to cart" type="submit" /></form>

Beware not to use the POST mode when in a form, since it adds a new `<form>` tag: you would end up with a form inside another, and the additional button would submit the first form.

As for `link_to`, the `confirm` and `popup` options can be added and combined:

    [php]
    <?php echo button_to('add to cart', 'shoppingCart/add?id=100', 'confirm=Are you sure? popup=true') ?>
    // will generate in HTML
    <input value="add to cart" type="button" onclick="if (confirm('Are you sure?')) {window.open('/fo_dev.php/shoppingCart/add/id/100.html');}" />

mail_to helper
-------------

The reason why symfony ships a `mail_to()` helper is that nowadays, email harvesting robots prowl about the web, and you can't display an email address on a website without becoming a spam victim within days.

This helper takes three parameters : the actual email address, the string that should be displayed and an array of options. If the third parameter is not set the email address is written non-crypted:

    [php]
    <?php echo mail_to('<EMAIL>', 'contact address') ?>
    // will generate in HTML
    <a href="mailto:<EMAIL>'>contact address</a>

If the flag is set to array('encode' => true) the displayed and pointed addresses are processed by a random decimal and hexadecimal entity encoder. This will probably not stop all address-harvesting spambots, but it will keep most of them away. Future versions of this helper will probably evolve as the harvesting techniques become more accurate.

    [php]
    <?php echo mail_to('<EMAIL>', 'contact address', array('encode' => true)) ?>
    // will generate in HTML something like
    <a href="&#109;&#x61;&#105;&#108;&#x74;&#x6f;&#58;&#x6d;&#121;&#x61;&#x64;&#x64;&#114;&#101;&#x73;&#115;&#64;&#x6d;&#x79;&#100;o&#x6d;&#97;&#105;&#110;&#46;&#x63;&#111;&#x6d;">&#x63;&#111;&#110;&#x74;&#x61;c&#x74;&#32;&#x61;d&#100;&#114;e&#115;&#x73;</a>

Image helper
------------

Considering that all your HTML pages are handled by actions, the `href` attribute is not a worry anymore. But what about all those tags having a `src` attribute? Symfony has image and javascript helpers that are faster to write and do most of the job themselves. 

In addition, future versions will support configuration for the default location of media files. This may prove helpful if you decided suddenly to host all of your project media files (css, js, pdf, jpg, gif, etc.) in a new server to increase performance.

To create an `<img>` tag:

    [php]
    <?php echo image_tag('test') ?>
    // will generate in HTML
    <img href="/images/test.png" alt="Test" />

By default, the image `test.png` will be looked for in the `/images/` directory of the web server (which is the `myproject/web/image/` directory of your file structure, unless you customized it). 

If you need to change the default file type or the default location, you can pass a more defined URL:

    [php]
    <?php echo image_tag('test.gif') ?>
    // will generate in HTML
    <img href="/images/test.gif" alt="Test" />
    
    <?php echo image_tag('/my_images/test.gif') ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" />

You can add a second argument to specify additional HTML attributes; this argument must be an array. 

    [php]
    <?php echo image_tag('/my_images/test.gif', array('class' => 'shortImage')) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" class="shortImage"/>

Don't bother to specify a `alt` attribute if your media file has an explicit name, since symfony will determine it for you.

To fix the size of an image, use the attribute `size`:

    [php]
    <?php echo image_tag('/my_images/test.gif', array('size' => '100x20')) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="Test" width="100" height="20"/>

To keep the code readable and let you write templates fast, the options argument can use an abbreviated string syntax:

    [php]
    <?php echo image_tag('/my_images/test.gif', 'size=100x20 alt=My new car class=shortImage onclick=showNextImage(); ') ?>
    // is the same as
    <?php echo image_tag('/my_images/test.gif', array('size' => '100x20', 'alt' => 'My new car', 'class' => 'shortImage' , 'onclick' => 'showNextImage();') ) ?>
    // will generate in HTML
    <img href="/my_images/test.gif" alt="My new car" width="100" height="20" class="shortImage" onclick="showNextImage();" />

JavaScript helper
-----------------

To link to JavaScript files, you can omit the path and the suffix: 

    [php]
    <?php echo javascript_include_tag('myscript') ?>
    // will generate in HTML
    <script language="javascript" type="text/javascript" src="/js/myscript.js">

Once again, the default location can be overridden in a function call for quick needs, or redefined for the whole site in the configuration files for major changes.

If you read the whole documentation, you will see that symfony gives you three different ways to require an additional JavaScript file. You should use them with this order of preference:

* parameter definition in the `view.yml` file: Most of the time, the best solution
* `$this->getResponse()->addJavascript()` method call from the action: When the name of the files to include depend on calculations made in the action
* `javascript_include_tag()` helpers in the template: To include a JavaScript file at a given position inside a template and not in the head.

The last solution is rarely good; if you need it, check whether your code needs some refactoring (for instance write a JavaScript function call in the code and require the script inclusion in the head). However, you sometimes don't have the choice, for instance if you have to include traffic measure scripts at the end of your pages.

>**Note**: You may be looking for a `stylesheet_tag()` helper, but there is none. If you need to include a custom stylesheet, you should not do it in the template but rather in the view or in the action, as described in the [view configuration chapter](templating_configuration.txt). This way, the declaration appears in the `<head>` instead of in the `<body>`.

Absolute paths
--------------

The url and asset helpers generate relative paths by default. You can easily add an `absolute=true` parameter to force the output to absolute paths, for instance for inclusions of links in an email, a RSS feed, or an API response.

    [php]
    <?php echo url_for('module/action', true) ?>
    <?php echo link_to('my link', 'module/action', 'absolute=true') ?>
    <?php echo image_tag('test', 'absolute=true') ?>
    <?php echo javascript_include_tag('myscript', 'absolute=true') ?>
{'fraction_non_alphanumeric': 0.11405088289962825, 'fraction_numerical': 0.01121050185873606, 'mean_word_length': 4.022316219369895, 'pattern_counts': {'":': 0, '<': 164, '<?xml version=': 0, '>': 188, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6192064', 'n_tokens_mistral': 10132, 'n_tokens_neox': 9532, 'n_words': 4353}