views:

265

answers:

4

I'm using Kohana 3 and it's template controller. My main site template controller currently looks something like this:

<?php defined('SYSPATH') or die('No direct script access.');

abstract class Controller_SiteTemplate extends Controller_Template
{
    public function before()
    {
        parent::before();

        // Initialize default template variables
        $this->template->styles           = Kohana::config('site.styles');
        $this->template->scripts          = Kohana::config('site.scripts');

        $this->template->title            = '';
        $this->template->content          = '';
    }
}

And then in my template view I do:

<?php # Styles
foreach($styles as $file => $media) 
    echo HTML::style($file, array('media' => $media)).PHP_EOL ?>

<?php # Scripts
foreach($scripts as $file) 
    echo HTML::script($file).PHP_EOL ?>

This works alright. The problem is that it requires the style- and script files to be added in the controller, which shouldn't really have to care about those. It also makes it a hassle if the views are done by someone else than me since they would have to fool around with the controller just to add a new stylesheet or a new script file. How can this be done in a better way?

Just to clearify, what I am wondering is how to deal with page specific stylesheets and scripts. The default and site-wide ones I have no problem with fetching from a config file or just put directly in the template view. My issue is how to add custom ones for specific pages in a good way.

A: 

One way to do it is to create a helper that stores a list of your CSS and Script files. This helper would work as a Singleton. Then, at the appropriate time you can dump these links inside your template.

ie:

Helper code:

<?php defined('SYSPATH') or die('No direct script access.');

class javascript {
    private static $files = array();

    public static function add($file)
    {
        self::$files[] = $file;
    }

    public static function get()
    {
        return self::$files;
    }
}

Controler code:

class Controller_Example extends Controller_Template {

    public function before()
    {
        ....
        javascript::add('js/jquery.js');
        javascript::add('js/jquery-ui.js');
        ....
    }
}

Template code:

<html>
    <head>
        <?php foreach(javascript::get() as $javascript ?>
        <script type="text/javascript" src="<?= $javascript ?>"></script> 
        <?php endforeach; ?>
    </head>
...
</html>

Several improvements to consider:

  • Creating a base class to serve as the template for the CSS version.
  • Adding a method to add script files that are included in the body, necessary for FBJS.

PS: this is the strategy one of the leads in the Kohana Project recommended once on IRC.

Phillip Whelan
Could they be added in the view as well? Cause in your example you add them in the Controller, which was the problem I was referring to. Of course jquery and jquery-ui I would add as default in the template controller, but I'm thinking of more page specific scripts and stylesheets.
Svish
+1  A: 

Controller_Template actually is the place to put the logic for styles and javascripts that are loaded regularly , that's why it's called Controller_Template.

You're supposed to add/edit them through controllers you're extending the Controller_Template with. And in the end, every developer that works with Kohana is supposed to first get to know how stuff works.

Concerning the inline scripts / styles, just put them in view files, they are inline, right ?

Kemo
Problem is that the view files are stuck into the body section in the template and at least stylesheets should be added to the head. Some say that scripts should be added last in the body, so I suppose they could be added there in the view actually, but yeah.
Svish
The problem is that the views in Kohana do not allow for putting in code that can be used in multiple places. Rails content_for method was ideal for this since you could had a content_for :head block in the view to add head specific changes for a view (styles, view specific meta tags, etc...). I would love to know how to do this in KO3.
Gerry
A: 

Hi,

Why dont you just put them in the view? - then if someone else is working on the views, they can see what stylesheets are in use and have control over them without touching the controllers etc?

eg:

<?php echo HTML::style("/css/style.css", array('media' => 'screen')).PHP_EOL ?>

Ian

ichilton
The issue is that stylesheets at least should be added to the head. And views are usually stuck in the body somewhere inside the template.
Svish
A: 
    parent::before();

    // Initialize default template variables
    $this->template->styles           = Kohana::config('site.styles');
    $this->template->scripts          = Kohana::config('site.scripts');

    $this->template->title            = '';
    $this->template->content          = '';

    /* make your view template available to all your other views so easily you could
       access template variable
    */
    View::bind_global('template', $this->template);

in a certain view use something like this

   $template->scripts[] = 'js/example.js';

and in main view (template view) at the end you will have a colected array of js from different views

  <?php
   foreach($template->scripts as $file) { echo Html::script($file), "\n"; }
  ?>

using this approach you must call render method on every view utilized (do this on top of template view script) and then insert variables with rendered content like bellow

$top = View::factory('elements/top_nav')->render();
$content = $content->render();
$footer = View::factory('elements/footer')->render();

<div id="content"> 
        <?php echo $content;?>
    </div>
    <div id="meniu"><?php echo $top;?></div> you could add inline scripts as well, just add a $template->inline_scripts populate it with $template->inline_scripts = array('<script type="text/javascript">Cufon.replace(\'#meniu ul.topnav li a\');</script>'); and show it on template view script with a foreach($template->inline_scripts as $inline_script) { echo $inline_script."\n";};

`

Gabriel Braila