We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Using assets from Module path

Hello ! I recently started to re-build an old project with Phalcon, and absolutely love it !

But now i like to know if it is possible to load assets from a path within modules root, that way modules could be packaged as complete set of Front and Back-End.

Loading assets with {{ assets.outputJs() }} is looking in Document Root of the project. For now i created a Controller that extends ControllerBase of the Module where users authorization is checked from session:

// ControllerBase
<?php
        if (! ($this->session->has('loggedIn') && $this->session->get('loggedIn')) ) {
            return $this->dispatcher->forward(
                [
                    'namespace' => 'My\Module\Ns',
                    'module' => 'admin',
                    'controller' => 'index',
                    'action' => 'login',
                ]
            );

        }

For loading the assets from a module, i created an AssetsController

<?php
class AssetsController extends ControllerBase
{
    public function jsAction($param)
    {
        /*
        * Path Location in module:
        * module
        * |-- admin
        * |----| controllers
        * |----|---- AssetsController.php
        * |----| js
        * |----|---- adminscript.js
        */
        $jsPath = realpath(__DIR__.'/..').'/js';

        if (is_file($jsPath.'/'.$param)) {
            $this->response->setContentType('application/javascript');
            $len = readfile($jsPath.'/'.$param);
            $this->response->setContentLength($len);
            $this->response->setContent(ob_get_contents());
            $this->view->disable();

            return $this->response->send();
        } else {
            return $this->router->notFound('/');
        }
    }
}

With the default route.php from phalcon's devtools it works when i attach the script in the requesting Controller with $this->assets->addJs('/admin/assets/js/adminscript.js'); and call it with {{ assets.outputJs() }} in *.volt. WIth this combination i can even attach scripts that should only be available to logged in users, to not have the admin scripts in a public accessible folder and to keep them out of Doc Root .

But scripts arent cached by the browser and it feels a little bit off by using a MVC Framework. Maybe someone has a better Solution, or i am missing something.

I prefer set the expiration time from Apache/nginx but you can do it with Phalcon too.

H5BP htaccess example or nginxconfig.io

In Phalcon follow your example. Setting expiration time on responses

if (is_file($jsPath.'/'.$param)) {
    $this->response->setContentType('application/javascript');
    $len = readfile($jsPath.'/'.$param);
    $this->response->setContentLength($len);
    $this->response->setContent(ob_get_contents());

    // expires in 2 months
    $expiryDate = new DateTime();
    $expiryDate->modify('+2 months');
    $this->response->setExpires($expiryDate);

    $this->view->disable();

    return $this->response->send();
} else {
    return $this->router->notFound('/');
}