Table Of ContentsPrevious topicNext topicThis Page |
Assets Management¶
Phalcon\Assets\Manager is available in the services container, so you can add resources from any part of the application where the container is available. Adding Resources¶Assets supports two built-in resources: CSS and JavaScripts. You can create other resources if you need. The assets manager internally stores two default collections of resources - one for JavaScript and another for CSS. You can easily add resources to these collections like follows: <?php
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function index()
{
// Add some local CSS resources
$this->assets->addCss("css/style.css");
$this->assets->addCss("css/index.css");
// And some local JavaScript resources
$this->assets->addJs("js/jquery.js");
$this->assets->addJs("js/bootstrap.min.js");
}
}
Then in a view, these resources can be printed: <html>
<head>
<title>Some amazing website</title>
<?php $this->assets->outputCss(); ?>
</head>
<body>
<!-- ... -->
<?php $this->assets->outputJs(); ?>
</body>
<html>
Volt syntax: <html>
<head>
<title>Some amazing website</title>
{{ assets.outputCss() }}
</head>
<body>
<!-- ... -->
{{ assets.outputJs() }}
</body>
<html>
For better pageload performance, it is recommended to place JavaScript at the end of the HTML instead of in the Local/Remote resources¶Local resources are those who are provided by the same application and they’re located in the document root of the application. URLs in local resources are generated by the ‘url’ service, usually Phalcon\Mvc\Url. Remote resources are those such as common libraries like jQuery, Bootstrap, etc. that are provided by a CDN. The second parameter of <?php
public function indexAction()
{
// Add some local CSS resources
$this->assets->addCss("//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css", false);
$this->assets->addCss("css/style.css", true);
$this->assets->addCss("css/extra.css");
}
Collections¶Collections group resources of the same type. The assets manager implicitly creates two collections: <?php
// Javascripts in the header
$headerCollection = $this->assets->collection("header");
$headerCollection->addJs("js/jquery.js");
$headerCollection->addJs("js/bootstrap.min.js");
// Javascripts in the footer
$footerCollection = $this->assets->collection("footer");
$footerCollection->addJs("js/jquery.js");
$footerCollection->addJs("js/bootstrap.min.js");
Then in the views: <html>
<head>
<title>Some amazing website</title>
<?php $this->assets->outputJs("header"); ?>
</head>
<body>
<!-- ... -->
<?php $this->assets->outputJs("footer"); ?>
</body>
<html>
Volt syntax: <html>
<head>
<title>Some amazing website</title>
{{ assets.outputCss("header") }}
</head>
<body>
<!-- ... -->
{{ assets.outputJs("footer") }}
</body>
<html>
URL Prefixes¶Collections can be URL-prefixed, this enables you to easily change from one server to another at any moment: <?php
$footerCollection = $this->assets->collection("footer");
if ($config->environment === "development") {
$footerCollection->setPrefix("/");
} else {
$footerCollection->setPrefix("http:://cdn.example.com/");
}
$footerCollection->addJs("js/jquery.js");
$footerCollection->addJs("js/bootstrap.min.js");
A chainable syntax is available too: <?php
$headerCollection = $assets
->collection("header")
->setPrefix("http://cdn.example.com/")
->setLocal(false)
->addJs("js/jquery.js")
->addJs("js/bootstrap.min.js");
Minification/Filtering¶
The following example shows how to minify a collection of resources: <?php
$manager
// These JavaScripts are located in the page's bottom
->collection("jsFooter")
// The name of the final output
->setTargetPath("final.js")
// The script tag is generated with this URI
->setTargetUri("production/final.js")
// This is a remote resource that does not need filtering
->addJs("code.jquery.com/jquery-1.10.0.min.js", false, false)
// These are local resources that must be filtered
->addJs("common-functions.js")
->addJs("page-functions.js")
// Join all the resources in a single file
->join(true)
// Use the built-in Jsmin filter
->addFilter(
new Phalcon\Assets\Filters\Jsmin()
)
// Use a custom filter
->addFilter(
new MyApp\Assets\Filters\LicenseStamper()
);
A collection can contain JavaScript or CSS resources but not both. Some resources may be remote, that is, they’re obtained by HTTP from a remote source for further filtering. It is recommended to convert the external resources to local for better performance. As seen above, the <?php
// These Javascripts are located in the page's bottom
$jsFooterCollection = $manager->collection("jsFooter");
// This a remote resource that does not need filtering
$jsFooterCollection->addJs("code.jquery.com/jquery-1.10.0.min.js", false, false);
// These are local resources that must be filtered
$jsFooterCollection->addJs("common-functions.js");
$jsFooterCollection->addJs("page-functions.js");
Filters are registered in the collection, multiple filters are allowed, content in resources are filtered in the same order as filters were registered: <?php
// Use the built-in Jsmin filter
$jsFooterCollection->addFilter(
new Phalcon\Assets\Filters\Jsmin()
);
// Use a custom filter
$jsFooterCollection->addFilter(
new MyApp\Assets\Filters\LicenseStamper()
);
Note that both built-in and custom filters can be transparently applied to collections.
The last step is to decide if all the resources in the collection must be joined into a single file or serve each of them
individually. To tell the collection that all resources must be joined you can use the If resources are going to be joined, we need also to define which file will be used to store the resources
and which URI will be used to show it. These settings are set up with <?php
$jsFooterCollection->join(true);
// The name of the final file path
$jsFooterCollection->setTargetPath("public/production/final.js");
// The script HTML tag is generated with this URI
$jsFooterCollection->setTargetUri("production/final.js");
If resources are going to be joined, we need also to define which file will be used to store the resources
and which URI will be used to show it. These settings are set up with Built-In Filters¶Phalcon provides 2 built-in filters to minify both JavaScript and CSS, their C-backend provide the minimum overhead to perform this task:
Custom Filters¶In addition to the built-in filters, you can create your own filters. These can take advantage of existing and more advanced tools like YUI, Sass, Closure, etc.: <?php
use Phalcon\Assets\FilterInterface;
/**
* Filters CSS content using YUI
*
* @param string $contents
* @return string
*/
class CssYUICompressor implements FilterInterface
{
protected $_options;
/**
* CssYUICompressor constructor
*
* @param array $options
*/
public function __construct(array $options)
{
$this->_options = $options;
}
/**
* Do the filtering
*
* @param string $contents
*
* @return string
*/
public function filter($contents)
{
// Write the string contents into a temporal file
file_put_contents("temp/my-temp-1.css", $contents);
system(
$this->_options["java-bin"] .
" -jar " .
$this->_options["yui"] .
" --type css " .
"temp/my-temp-file-1.css " .
$this->_options["extra-options"] .
" -o temp/my-temp-file-2.css"
);
// Return the contents of file
return file_get_contents("temp/my-temp-file-2.css");
}
}
Usage: <?php
// Get some CSS collection
$css = $this->assets->get("head");
// Add/Enable the YUI compressor filter in the collection
$css->addFilter(
new CssYUICompressor(
[
"java-bin" => "/usr/local/bin/java",
"yui" => "/some/path/yuicompressor-x.y.z.jar",
"extra-options" => "--charset utf8",
]
)
);
In a previous example, we used a custom filter called <?php
use Phalcon\Assets\FilterInterface;
/**
* Adds a license message to the top of the file
*
* @param string $contents
*
* @return string
*/
class LicenseStamper implements FilterInterface
{
/**
* Do the filtering
*
* @param string $contents
* @return string
*/
public function filter($contents)
{
$license = "/* (c) 2015 Your Name Here */";
return $license . PHP_EOL . PHP_EOL . $contents;
}
}
Custom Output¶The <?php
use Phalcon\Tag;
$jsCollection = $this->assets->collection("js");
foreach ($jsCollection as $resource) {
echo Tag::javascriptInclude(
$resource->getPath()
);
}
|