ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Template Library Version 1.4

August 17, 2008 9:13pm

Subscribe [38]
  • #1 / Aug 17, 2008 9:13pm

    Colin Williams's avatar

    Colin Williams

    2601 posts

    Template 1.4.1 has been released. Please upgrade.

    Template Library Version 1.4 has been released. Version 1.4 introduces a method for dynamically setting the master template file.

    ——————————————————————————————————————————-

    Visit the Template Library Homepage

    View the Change Log

    Still using Template 1.3? See the Ignited Code thread covering Template 1.3

    ——————————————————————————————————————————-

    What’s New in Version 1.4?

    Version 1.4 adds a set_master_template() method which allows loading of different master template files that share all other aspects of the given template configuration. This can be utilized in theming setups where different theme templates share the same regions. This is the last piece of the puzzle to make template configurations 100% dynamic.

    ——————————————————————————————————————————-

    The Template library, written for the CodeIgniter PHP-framework, is a wrapper for CI’s View implementation. Template is a reaction to the numerous questions from the CI community regarding how one would display multiple views for one controller, and how to embed “views within views” in a standardized fashion. In addition, Template provides extra Views loading capabilities and shortcuts for including CSS, JavaScript, and other common elements in your final rendered HTML.

    Using Template looks like this:

    $this->template->write('title', 'Introduction to Template');
    $this->template->write_view('content', 'blog/posts', $this->blog->get_posts());
    $this->template->render();

    Look interesting? Head over to the Template Library Homepage to begin using Template in your next CodeIgniter application.

  • #2 / Aug 18, 2008 2:58am

    Devil103

    1 posts

    Hello there,

    I’m a new Codeigniter user and have been working with it for a week or so now. I quickly came across the need for your template library but I do have some questions. Since this is a new project I’ve already started to implement AJAX into the website but I’ve run into a bit of a pickle.

    My controllers are all setup to render the master template with data at the end of the each function that requires a view. But when I use the prototype/scriptaculous library to dynamically fetch some new content I want to be able to use the same controller and function and only update part of the view. I know I’m not making myself very clear right now so I’ll just explain it in code.

    function DisplayForm () {
              $this->load->helper('form');
              $this->load->model('contact_model');
              $this->load->library('template');
              $contactpersons = $this->contact_model->getContacts();
              foreach ($contactpersons as $row)
              {
                  $options[$row->id] = $row->contact;
                  
              }
              $data['form'] = form_open('[removed]submitContact()', array('id' => 'contactForm'));
              $data['form'] .= form_input('name') . "
    ";
              $data['form'] .= form_input('email') . "
    ";
              $data['form'] .= form_dropdown('contact', $options) . "
    ";
              $data['form'] .= form_textarea(array('id' => 'txtMessage', 'name' => 'message'));
              $data['form'] .= form_submit('cmdSubmit', 'Verzenden!');
              $this->template->write('title', 'Contacteer ons');
              $this->template->write('bd', $data['form']);
              $this->template->render();
          }

    Now this works great when a user surfs to site_url(contact/displayform). But when I use AJAX to update only one div, it off course ‘rerenders’ the entire view (header, footer and body) into the div while I only want to render the body. I hate to have to define two functions for page update so there must be a better way to handle this? I’ve already tried using

    echo render('bd')

    but then I’m faced with the problem that a new page load also only renders the body and not the header and footer

    Thanks

    Kevin

  • #3 / Aug 18, 2008 3:18am

    Colin Williams's avatar

    Colin Williams

    2601 posts

    All you need to do is check that the request was AJAX or not. Also, when you supply render() with a region name, it only returns the content, it does not echo it. Here’s a rewrite of your code:

    function DisplayForm () {
              // Create an ajax check… might be more useful to do this in the constructor and set $this->ajax
              $ajax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'));
    
              $this->load->helper('form');
              $this->load->model('contact_model');
              $this->load->library('template');
              $contactpersons = $this->contact_model->getContacts();
              foreach ($contactpersons as $row)
              {
                  $options[$row->id] = $row->contact;
                  
              }
              $data['form'] = form_open('[removed]submitContact()', array('id' => 'contactForm'));
              $data['form'] .= form_input('name') . "
    ";
              $data['form'] .= form_input('email') . "
    ";
              $data['form'] .= form_dropdown('contact', $options) . "
    ";
              $data['form'] .= form_textarea(array('id' => 'txtMessage', 'name' => 'message'));
              $data['form'] .= form_submit('cmdSubmit', 'Verzenden!');
              $this->template->write('title', 'Contacteer ons');
              $this->template->write('bd', $data['form']);
    
              // Check for ajax
              if ( ! $ajax)
              {
                  $this->template->render();
              }
              else
              {
                  echo $this->template->render('bd');
              }
          }
  • #4 / Aug 21, 2008 7:02am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Hi Colin,

    I have my default template setup as following:

    $template['default']['template'] = 'default.tpl';
    $template['default']['regions'] = array(
       'header' => array(
               'title' => '',
            'extension' => ''
        )
    );

    How can I set the ‘title’ for every page.

    I know that I need to use $this->template->write, but not quite sure how you made it work from there.

    Edit:
    Also is it possible to add a folder directory for the selected template.

    This would come in handy if using themes, that way a user can set the directory in which the theme is held in without referring to it every time they need to call a view. If no directory is specified then the system would use the default application/views 😊

    set_template_directory //hint
  • #5 / Aug 21, 2008 7:22am

    Colin Williams's avatar

    Colin Williams

    2601 posts

    Hi Milos. You can set a default title in the regions config

    $template['default']['regions'] = array(
       'title' => array(
          'content' => array('Default Title'),
       ),
    )

    Notice how $template[‘default’][‘regions’][‘title’] and $template[‘default’][‘regions’][‘title’][‘content’] are arrays? A bit messy, yeah. This is probably going to change in the next release, where you’ll just be able to do $template[‘default’][‘regions’][‘title’] = ‘Default Title’;

    And for the theming/sub-folder setting, I actually had that feature completely set in place just before I released 1.1. One scenario I kept coming to is that the theming feature only works for Template methods, and so the API wouldn’t be as congruent with $this->load->view(). Feel free to convince me to factor it back in for the next release though! I still like the idea minus that one caveat.

  • #6 / Aug 21, 2008 7:36am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Notice how $template[‘default’][‘regions’][‘title’] and $template[‘default’][‘regions’][‘title’][‘content’] are arrays? A bit messy, yeah. This is probably going to change in the next release, where you’ll just be able to do $template[‘default’][‘regions’][‘title’] = ‘Default Title’;

    Maybe if its possible to make it something like this:

    $this->template->write('region/attribute/content', 'value')

    So by doing it this way, it would allow anyone to easily add/modify content within regions without making is messy.

    And for the theming/sub-folder setting, I actually had that feature completely set in place just before I released 1.1. One scenario I kept coming to is that the theming feature only works for Template methods, and so the API wouldn’t be as congruent with $this->load->view(). Feel free to convince me to factor it back in for the next release though! I still like the idea minus that one caveat.

    Well as I suggested before it could be as simple as just adding another config item:

    $template['default']['directory'] = 'my_special_folder_name';

    If this value is not set within the config file, or not set by calling something like

    $this->template->set_template_dir('value')

    then the whole library would not add the directory to the beginning of all views, and instead look in the default views folder at root level rather then the specified folder level.

    Just a thought. Would love to hear what you think.

  • #7 / Aug 22, 2008 6:11pm

    Colin Williams's avatar

    Colin Williams

    2601 posts

    Right, Milos. Like I said, the whole theming directory idea was already in place at one time and it was just as simple as you envisaged. However, let’s assume at some point in the application, a programmer decides to use $this->load->view() instead of one of the available Template methods (and there are often situations where doing this makes sense). The load->view() method knows nothing of the Template theme, so the API breaks down. The programmer would be required to pass the theme directory in each instance he uses load->view().

    $content = $this->load->view($this->template->theme .'view_file', $data, TRUE)

    So, it’s something I would consider adding back in, so long as the above caveat is made clear.

    So by doing it this way, it would allow anyone to easily add/modify content within regions without making is messy.

    I’m not sure I follow. Currently, regions have only 4 attributes: content, name, wrapper and attributes.

    Wrapper and attributes I haven’t found much use for and I don’t even really promote the use of them. Content must be an array just because that’s the data structure Template works with (but again I’m going to shift that burden from the config file)

  • #8 / Aug 23, 2008 3:41am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Right, Milos. Like I said, the whole theming directory idea was already in place at one time and it was just as simple as you envisaged. However, let’s assume at some point in the application, a programmer decides to use $this->load->view() instead of one of the available Template methods (and there are often situations where doing this makes sense). The load->view() method knows nothing of the Template theme, so the API breaks down. The programmer would be required to pass the theme directory in each instance he uses load->view().

    $content = $this->load->view($this->template->theme .'view_file', $data, TRUE)

    So, it’s something I would consider adding back in, so long as the above caveat is made clear.

    Yes, that would be how you would do it if you were to use the CI format. OR if you don’t want to use the Template library at all just put in the path yourself, which wouldn’t be any different to users currently applying themes to their solutions.

    So by doing it this way, it would allow anyone to easily add/modify content within regions without making is messy.

    I’m not sure I follow. Currently, regions have only 4 attributes: content, name, wrapper and attributes.

    Wrapper and attributes I haven’t found much use for and I don’t even really promote the use of them. Content must be an array just because that’s the data structure Template works with (but again I’m going to shift that burden from the config file)

    Well my config file array looks something like this:

    $template['default']['regions'] = array(
        'header' => array(
           'content' => array('<h1>Welcome</h1>','Hello World'),
           'name' => 'Page Header',
           'wrapper' => '<div>',
           'attributes' => array('id' => 'header', 'class' => 'clearfix')
        )
     );

    I’m not sure if this is possible that why I made the suggestion in the previous post. To adjust the header content attribute I’d need to so something like:

    $this->template->write('header/content','value');

    Which would make sense and be simple to use(?). Since I don’t seem to be having luck doing it any other way.

  • #9 / Aug 23, 2008 4:25am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    The other thing is, I’m not sure how possible this is.

    But if I wanted to define and set a region at the same time, how would I go about it?

    $this->template->add_region('value')->write('value','some value')?
  • #10 / Aug 23, 2008 5:28pm

    Colin Williams's avatar

    Colin Williams

    2601 posts

    Honestly, I’m not sure what’s required to get method chaining to work, but I would assume a method must return a reference to the object for each method that is chainable. You would just have to make it two lines as far as I know:

    $this->template->add_region('region');
    $this->template->write('region', 'content');

    I’m not sure if this is possible that why I made the suggestion in the previous post. To adjust the header content attribute I’d need to so something like…

    Still not sure if I’m following, but you can overwrite a regions contents by passing a third param of TRUE to the write() method, like $this->template->write(‘region’, ‘content’, TRUE). You can also clear out a region with $this->template->empty_region(‘region’)

  • #11 / Aug 24, 2008 10:04am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Honestly, I’m not sure what’s required to get method chaining to work, but I would assume a method must return a reference to the object for each method that is chainable. You would just have to make it two lines as far as I know:

    $this->template->add_region('region');
    $this->template->write('region', 'content');

    I’m not sure if this is possible that why I made the suggestion in the previous post. To adjust the header content attribute I’d need to so something like…

    Still not sure if I’m following, but you can overwrite a regions contents by passing a third param of TRUE to the write() method, like $this->template->write(‘region’, ‘content’, TRUE). You can also clear out a region with $this->template->empty_region(‘region’)

    The region’s issue (?) that I’m having is with multi dimension arrays. How can I set their values? Say if I have something like:

    $template['theme_name']['regions'] = array(
        'header' => array(
                            'title' => 'Title',
                            'account' => 'Anonymous'
                        ),
        'navigation' => array(
                            'selected' => 1,
                            'type' => 'classic'
                        ),
        'content' => 'Heaps of text can go here.',
        'footer' => 'Goodbye!'
    );

    How would I go about setting for example the ‘title’ in the ‘header’? Or any other item that is not in the first layer?

  • #12 / Aug 24, 2008 4:34pm

    Colin Williams's avatar

    Colin Williams

    2601 posts

    Simply put, regions are not multidimensional. They don’t hold additional attributes like you’ve laid out here. Regions are just placeholders for content. That content can be generated in anyway you choose, but typically it is with Views.

    If you need additional variables available to your master template that are not regions, use the tried and trusted $this->load->vars() method in CI.

  • #13 / Aug 24, 2008 7:31pm

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Can $this->load->vars() be used with other template parsers other then the default CI $this->load->view() or $this->parser->parse()?

  • #14 / Aug 24, 2008 7:41pm

    Colin Williams's avatar

    Colin Williams

    2601 posts

    This function takes an associative array as input and generates variables using the PHP extract function. This function produces the same result as using the second parameter of the $this->load->view() function above. The reason you might want to use this function independently is if you would like to set some global variables in the constructor of your controller and have them become available in any view file loaded from any function. You can have multiple calls to this function. The data get cached and merged into one array for conversion to variables.

    Doesn’t say anything specific about the Template Parser class, but certainly covers Views. I don’t use template parsers ever so it’s not something I’ve come across. Should be easy enough to check.

  • #15 / Aug 25, 2008 5:54am

    Milos Dakic's avatar

    Milos Dakic

    114 posts

    Doesn’t say anything specific about the Template Parser class, but certainly covers Views. I don’t use template parsers ever so it’s not something I’ve come across. Should be easy enough to check.

    Yeah I don’t think it works. Unless I’m doing something wrong.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases