CodeIgniter Forums
An easy way to execute a method from the view .. - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: An easy way to execute a method from the view .. (/thread-10445.html)

Pages: 1 2


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]mvdg27[/eluser]
Hi guys,

I have been reading a bit on the forum about this, but didn't really ended up with a good solution.

I'm trying to achieve a very simple thing, I think:

From my view I want to be able to execute some methods that are defined in the controller. For example I want to call "$this->website->menu()", or "$this->website->children(4)" (the subpages of element with id = 4), or "$this->website->users_online()".

The context of this questions is a CMS I'm currently building, where I want to give designers the opportunity to easily retrieve exactly the data they need from the system. Instead of preparing every possible piece of data on the server on a page load, and then see whatever gets used, it sounds smarter to only do the processes that are actually needed.

Does anyone have an idea on how to achieve this?

Thanks!


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]srobet[/eluser]
You can write it at library.

Menu example
Library
Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');



class Templating{
function top_menu()
{
     $themenu='<ul><li>Sample Menu</li></ul>';
     $return $themenu;
}
}

In Controller load this library and call the menu function.
Code:
function index()
{
    $this->load->library('templating');
    $data['top_menu']=$this->templating->top_menu();
    $this->load->view('the_template',$data);
}

And at your views code, designer just write :
Code:
&lt;?=$top_menu;?&gt;
to create the top menu.


CMIIW


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]mvdg27[/eluser]
Ah yes that works of course .. but that still means that all the code is being executed no matter what the designer uses. Right now I just might have 10 different functions or so, but imagine it being 100 .. then this approach is not that efficient anymore, I guess.

I'm now experimenting with putting it in helper, as such:

Code:
function top_menu() {
    $CI =& get_instance();
    $CI->db->where('parent', 0);
    $query = $CI->db->get('menu');
    return $query->result('array');
}

Allowing the designer to simply do:

Code:
<ul>
&lt;?
foreach(top_menu() as $menu_item) {
?&gt;
  <li>&lt;?=$menu_item['label']?&gt;</li>
&lt;?
}
?&gt;
</ul>

That's sort of the idea I have in mind. Off course I could also have a function that already creates a ready made unordered list ect. But for now I'm interested if there are any flaws in this concept?

Thanks


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]Tom Glover[/eluser]
You can assign the method to a var in the controller then pass and call the var in the view file.


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]srobet[/eluser]
This function i use now into my library for top menu:
Code:
function top_menu()

    {

        $CI =& get_instance();

        $CI->db->order_by('page_order');

        $querytop=$CI->db->get_where('page',array('publish'=>1,'top_page'=>0,'position_id'=>0));

        $top_page='';

        $top_page.='<li>'.anchor('','Home').'</li>';

        foreach($querytop->result() as $rowstop)

        {

            $CI->db->order_by('page_order');

            $querysub=$CI->db->get_where('page',array('publish'=>1,'top_page'=>$rowstop->page_id));

            $totalsub=$querysub->num_rows;

            if($totalsub==0)

                $top_page.='<li>'.anchor($rowstop->slug,$rowstop->menu_display).'</li>';

            else

            {

                $top_page.='<li>'.anchor($rowstop->slug,$rowstop->menu_display,array('class'=>'MenuBarItemSubmenu'));

                $top_page.='<ul>';

                foreach($querysub->result() as $rowsub)

                {

                    $top_page.='<li>'.anchor($rowsub->slug,$rowsub->menu_display).'</li>';    

                }

                $top_page.='</ul></li>';

            }

        }

        return $top_page;

    }

This function support 2 level submenu


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]mvdg27[/eluser]
@srobet .. thanks for your reply .. Indeed I'm working on a full menu-tree as well

@WackyWebs.net .. if you assign a method to a var, can you still pass variables to the method? And are you sure it isn't executed directly when it is assigned to the var? That's exactly the kind of behaviour I want to prevent!


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]Tom Glover[/eluser]
It is executed directly when assigned, so in theory the output is assigned to the var.

You can still pass variable to the method.

Code:
$var1 = $this->test_lib->test($var2,true); // Method assigned to var1, and var 2 and the true are passed to the method



An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]wiredesignz[/eluser]
This is terrible code, both the library and the helper methods are acting as Models and the Library is also creating HTML.

Firstly a View can access a Model directly, CI even assigns loaded Libraries and Models to the view loader for you.

You should both really rethink your application design.


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]srobet[/eluser]
I think is not so terrible code. Because the main purpose of mvdg27's is to generate the menu for templating.

CMIIW


An easy way to execute a method from the view .. - El Forum - 07-31-2008

[eluser]wiredesignz[/eluser]
I'm not going to try to teach you MVC here, but there are far better ways to achieve templating.

Call the model from the view
Code:
//view
<ul>
&lt;?php
    if ($items = $this->menu_model->get_data(array('site','nav'))):
        foreach ($items as $k => $item):
            $active = ($item->uri == $page) ? array('class' => 'current') : NULL;
            echo '<li>', anchor($item->uri, $item->title, $active), '</li>';
        endforeach;
    endif;
?&gt;
</ul>

Pass the data into the view
Code:
//controller
$data['items'] = $this->menu_model->get_data(array('site','nav'));

//view
<ul>
&lt;?php
    if ($items):
        foreach ($items as $k => $item):
            $active = ($item->uri == $page) ? array('class' => 'current') : NULL;
            echo '<li>', anchor($item->uri, $item->title, $active), '</li>';
        endforeach;
    endif;
?&gt;
</ul>

Pass a reference to the model into the view
Code:
//controller
$data['menu'] =& $this->menu_model;

//view
<ul>
&lt;?php
    if ($items = $menu->get_data(array('site','nav'))):
        foreach ($items as $k => $item):
            $active = ($item->uri == $page) ? array('class' => 'current') : NULL;
            echo '<li>', anchor($item->uri, $item->title, $active), '</li>';
        endforeach;
    endif;
?&gt;
</ul>