Part of the EllisLab Network
   
3 of 12
3
Proposal: View Library (updated x3!)
Posted: 04 June 2007 04:45 PM   [ Ignore ]   [ # 31 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1749
Joined  06-23-2006

Agree 100%. Good eye.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 05 June 2007 04:52 AM   [ Ignore ]   [ # 32 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2916
Joined  07-27-2006

Whoa. Somehow this slipped off my radar, but I coded practically this exact same thing a couple days ago. I definitely prefer this kind of syntax over the default CI implementation of the Loader class.

Although, I called mine Template, and your set() is my write(), and your part() is my write_view().

Cool stuff. I like the idea of partial caching. Some things I’m adding to mine is the ability to maintain pieces of the “template” in the user’s session, so we can redirect the user but keep things like error messages, status messages, or anything they wanted to maintain throughout a process that might involve several redirects (it’s flushed once it is displayed); and a more abstract way of adding links/scripts/meta tags to the HEAD.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 06 June 2007 03:17 AM   [ Ignore ]   [ # 33 ]  
Summer Student
Avatar
Total Posts:  15
Joined  06-01-2006

I would add these 2 functions, they were useful for me ...

function appendToArrayVar($k, $v){
    $t
= $this->get($k);
    if(!
is_array($t)) $t = array($t);
    if(
is_array($v)) $t = array_merge($t, $v);
    else
array_push($t, $v);
    
$this->set($k, $t, true);
}

function appendToVar($k, $v){
    $t
= $this->get($k);
    
$t .= $v;
    
$this->set($k, $t, true);
}

Edited to add array_merge ...

Profile
 
 
Posted: 07 June 2007 08:43 AM   [ Ignore ]   [ # 34 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  211
Joined  02-14-2007

@coolfactor:  I’ve been using your View library and it has really simplified the dynamic building of Views.  One question, in my application I have one shared header partial view that is used by all controllers that loads all standard CSS and JS, however, one of my controllers utilizes additional CSS and JS files for Lightbox functionality.  Is there an easy way to use your View library to dynamically load a group of additional HEAD content for specific controllers, while still using one shared header.php partial view.

I am trying to follow the style used by Derek in BambooInvoice with the $extraHeadContent variable.  In the header.php file I added: <?php if (isset($extraHeadContent)) { echo $extraHeadContent;  } ?>. 

Does your “append” function enable the building of a string via concatenation that could then be loaded into an $extraHeadContent variable.  I was also looking into using your partials functionality, but it does not look like I can use the linkCSS/linkJS functions as function parameters to $this->view-part().  I was thinking of adding an extra option to the “part” method to work like this: $this->view->part(‘extraHeadContent’, $this->view->linkJS(’../js/slimbox.js’), ‘append’);

Any suggestions?

Profile
 
 
Posted: 07 June 2007 08:52 AM   [ Ignore ]   [ # 35 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  647
Joined  09-30-2006
Colin Williams - 05 June 2007 04:52 AM

Whoa. Somehow this slipped off my radar, but I coded practically this exact same thing a couple days ago. I definitely prefer this kind of syntax over the default CI implementation of the Loader class.

Although, I called mine Template, and your set() is my write(), and your part() is my write_view().

Cool stuff. I like the idea of partial caching. Some things I’m adding to mine is the ability to maintain pieces of the “template” in the user’s session, so we can redirect the user but keep things like error messages, status messages, or anything they wanted to maintain throughout a process that might involve several redirects (it’s flushed once it is displayed); and a more abstract way of adding links/scripts/meta tags to the HEAD.

Colin, are you going to share yours with other Igniters? I’d like to see/try it.

Thanks

 Signature 

sitesquad.net | < insert catchy tagline here />

Profile
 
 
Posted: 07 June 2007 09:02 AM   [ Ignore ]   [ # 36 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1749
Joined  06-23-2006
Neovive - 07 June 2007 08:43 AM

I have one shared header partial view that is used by all controllers that loads all standard CSS and JS, however, one of my controllers utilizes additional CSS and JS files for Lightbox functionality.  Is there an easy way to use your View library to dynamically load a group of additional HEAD content for specific controllers, while still using one shared header.php partial view.

Are you using the linkCSS() and linkJS() methods of the View library? Here what I would do.

Have a single header.php file that is included by all controllers. It would contain all the links to CSS and JS that are common to all or most pages. No need to dynamically add those to the view since they are always needed.

header.php

<head>
    <
title>My Fancy Website</title>

    <!-- include
common stuff in here -->
    <
link type="text/css" href="/css/common_styles.css" />
    <
scrpt type="text/css" href="/js/common_functions.js"></scrpt>

    <!--
variables for dynamic stuff -->
    
<?php echo $view_css; ?>
    <?php
echo $view_js; ?>

</head>

Then, in your controllers, you might have this:

$this->view->part('header', 'header.php');

You’d be assigning the contents of the header.php file to the $header variable in your template. So far, so good.

Because header.php contains variables for CSS and JS, your controllers can add whatever they want. The order you do it is irrelevant (as long as you have the latest version of the View library).

So, in your controller’s constructor you might set some CSS and JS common to all or most functions of that controller. Doing it in the constructor is just one solution when multiple functions need to do the same thing.

$this->view->linkCSS('/css/first_styles.css');
$this->view->linkCSS('/css/second_styles.css');
$this->view->linkJS('/js/some_functions.js');

I’m not familiar enough with Lightbox, but if it had some CSS and JS needed, it could also link to the necessary file:

$CI =& get_instance();
$CI->view->linkCSS('/css/lightbox_styles.css');
$CI->view->linkJS('/js/lightbox_functions.js');

And then, when you’re ready to render your finished page, you simply call:

$this->view->load('template_name');

And everything is compiled and assigned to the view in one fell swoop.

Does that help?

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 07 June 2007 10:00 AM   [ Ignore ]   [ # 37 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  211
Joined  02-14-2007

That worked perfectly!  I should have looked more closely at the code for linkCSS() and linkJS(), as you already built-in the concatenation option smile.

Thank you so much for all of your support and for all of your great contributions to CI.

Profile
 
 
Posted: 07 June 2007 02:41 PM   [ Ignore ]   [ # 38 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2916
Joined  07-27-2006

Colin, are you going to share yours with other Igniters? I’d like to see/try it.

I’ve got a lot of goodies coming together for the community, including my version of this library, a user library, and a variable library that extends on the config library. I’m going to try to launch a dedicated site when they’re ready. My play time is often limited, so no promises smile

PM me for more details

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 08 June 2007 01:06 PM   [ Ignore ]   [ # 39 ]  
Summer Student
Total Posts:  1
Joined  06-08-2007

Thanks coolfactor, this is really nice to use, when working with numerous part views.

There is one thing which I don’t properly understand, the caching of the part view.
No matter what I try, I always seem to get the whole view cached.

I have as an example a simple controller with 1 views includes 2 part views.
Main view, containing
Content view, which I want cached.
Updates view, which I do not want cached.

Can anyone give some clues or pointers as to how this is done.
Can this be done?
Thanks

Profile
 
 
Posted: 08 June 2007 01:24 PM   [ Ignore ]   [ # 40 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1749
Joined  06-23-2006

Part caching is not supported by the View library I submitted, but there is definitely interest in the idea. Colin (see earlier post) is working on partial caching.

Here’s how I was going to implement it:

if ( ! $this->view->partIsCached('partial_var')) {

    
// do all the work for the partial that you normally want to avoid
    // ie. database queries, etc.

}
$this
->view->part('partial_var', 'path/to/partial', 30);  // cache for 30 minutes

Partial caching is rather complex. You need to execute code conditionally based on whether or not the partial is already cached. Otherwise, you’re not saving yourself any processing cycles and performance. But checking to see if the partial is cached introduces overhead anyway. This is primarily why I have never finished this… because I don’t see the advantages, for my sites anyway.

There may be other approaches I haven’t thought of yet, so I welcome your ideas and feedback.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 08 June 2007 02:01 PM   [ Ignore ]   [ # 41 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  647
Joined  09-30-2006

Just wanting to add my two words of wisdom to CF’s last message…

Without having any empirical data to back up my thoughts, I believe that partial caching is only necessary for the most demanding websites and if they run on older hardware or overtaxed web or database servers.

CI’s core implementation - which is NOT partial - offers an effective solution, primarily because it circumvents the need for having the entire framework being loaded before returning a cached response. So I would a assume that caching partials in the view requires basically everything to be loaded. What you shave off is the evaluation of some PHP code and perhaps database queries.

On modern systems you can crank a lot of PHP without even having to worry about load. Connecting to databases can be more expensive and thus Rick had addressed that with DB caching option. Another smart move that reflects real world experience.

That said - if you have some control over your server environment you can further minimize php code execution by installing an accelerator like Zend Optimizer which is free.

I’ve also been running Zend Platform on my dev machine and one of my servers and it cuts down even more than optimizer. But it’s not free. It does make your sites wickedly fast however and provides transparent dynamic caching. Extremely cool. Adding CI’s default caching to that turns page loads that would take 0.1 sec without any performance enhancements to 0.0034 sec.

Bottom line - if you’re in charge of the hardware and it’s fairly modern, your better off investing into available solutions than spending time writing a partial caching solution.

Cheers!

 Signature 

sitesquad.net | < insert catchy tagline here />

Profile
 
 
Posted: 08 June 2007 02:28 PM   [ Ignore ]   [ # 42 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2916
Joined  07-27-2006

My library does not provide partial caching. Sorry if I gave the wrong impression.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 20 June 2007 05:36 PM   [ Ignore ]   [ # 43 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  147
Joined  09-24-2006

Hi Coolfactor, nice library! Was wondering your thoughts on something, I currently use a library with a set_var() funcion which sets various placeholders in a template view. Was thinking perhaps i could just use your view library:

Page Library:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class
Page {
    
    
var $data = array();
    var
$CI;
    
    function
Page(){
        
        $this
->CI =& get_instance();
        
// This fills a session with an array of the current user's roles (ACL).
        
$this->user_auth->set_roles();
        
    
}
    
    
function set_var($var, $value) {
        $this
->data[$var] = $value
    }
    
    
function display(){
        $this
->CI->load->view('template', $this->data);
    
}
}

?>

Welcome Controller:

<?php

class Welcome extends Controller {

    
function Welcome(){
        parent
::Controller();
        
// $this->load->library('page');// this is autloaded
    
}
    
    
function index(){
        $this
->page->set_var('title', 'Welcome');
        
// load this controllers content
        
$this->page->set_var('content', $this->load->view('welcome', NULL, true));
        
$this->page->display();
    
}
}
    
    ?>

Template View

<html>
     <
head>
        <
title><?=$title?></title>
     <!--
common css and javascript loaded here -->
     </
head>
     <
body>
       <
div id="wrap">
           <
div id="content">
             
<?=$content?>   
           
</div>
          <
div id="foot">
             
This is my footer
          
</div>
       </
div>
    </
body>
</
html>

Proposed alternative:

/*
Get rid of Page Library and common view
*/
Welcome Controller:

<?php
class Welcome extends Controller {

    
function Welcome(){
        parent
::Controller();
                
// This fills a session with an array of the current user's roles (ACL).
        
$this->user_auth->set_roles();
        
// $this->load->library('view');// this is autloaded
        
$this->view->part('header', 'header.php');
        
$this->view->part('footer', 'footer.php');
    
}
    
    
function index(){
        $this
->view->set('title', 'Welcome');
        
// load this controllers content
        
$this->view->load('welcome');
    
}
}

Welcome View:

<?=$header?>
          
<h1>Welcome to my site!</h1>
          <
p>Simply by naming your class files identically to a native library will cause CodeIgniter to use it instead of the native one.</p>
<?=$footer?>

What do ya think?

Anyway feedback much appreciated :D

Profile
 
 
Posted: 20 June 2007 05:45 PM   [ Ignore ]   [ # 44 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  1749
Joined  06-23-2006

Looks good. smile

Not sure what else to say. You’re on the right track.

 Signature 

Mac OS X 10.4.10, Apache 1.3.3, PHP 5.2.3, CodeIgniter 1.5.x., baby!

Profile
 
 
Posted: 20 June 2007 05:49 PM   [ Ignore ]   [ # 45 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  147
Joined  09-24-2006

Great. So you think my proposed alternative makes much more sense?

Profile
 
 
   
3 of 12
3
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 819, on March 11, 2010 10:15 AM
Total Registered Members: 119534 Total Logged-in Users: 51
Total Topics: 125766 Total Anonymous Users: 5
Total Replies: 661786 Total Guests: 496
Total Posts: 787552    
Members ( View Memberlist )