Welcome Guest, Not a member yet? Register   Sign In
nested view variable "scope".
#1

[eluser]vecima[/eluser]
Hello all, I have what I think is an interesting problem.

I've made a blog (originally from the CI tutorial - but with a bazillion features added), and the "administration" of that blog happens inline rather than with some front end and back end controllers and views. basically, everyone reads the blog, and if you happen to be logged in as an administrator, you see extra links to edit/delete/etc blogs and comments.

Since this is going to be a community shared blog, some of the blogs (there are different types, but that doesn't matter for this) need to be approved by an admin. comments do not need to be approved.

so, without further delay, the code:

The controller:
Code:
class A extends Controller {

    function A()
    {
        parent::Controller();
        
        //load stuff
    }

    function index()
    {
        //gather data

        //load view
    }
    
    function comments()
    {
        //gather data

        //gather comments
        
        //load view
    }
}

The view loaded by the comments method:
Code:
<div>
    ...
    //rendering the blog
    //$blog is a variable with the data we need
    ...

    //this is the area to do admin things to the blog
    $admin_tools_data = array(
        'controller'        => $controller,
        'approval_function'    => 'approve_blog',
        'edit_function'        => 'edit_blog',
        'delete_function'    => 'delete_blog',
        'item_id'        => $blog['item_id'],
    );
                
    $this->load->view('admin_tools', $admin_tools_data);

    ...
    
    //rendering the comments
    foreach($comment_array as $comment)
    {
        $admin_tools_comment_data = array(
            'controller'        => $controller,
            'edit_function'        => 'edit_comment',
            'delete_function'    => 'delete_comment',
            'item_id'        => $comment['item_id'],
            'comment_id'        => $comment['id']
        );
        
        $this->load->view('admin_tools', $admin_tools_comment_data);


        //render this individual comment
        ...
    }
</div>

The admin_tools view loaded twice above:
Code:
<div class='admin_tools'>
    &lt;?php
        //default the variables so views only have to set the ones they want.
        $controller        = (isset($controller)) ? $controller : NULL;
        $approval_function    = (isset($approval_function)) ? $approval_function : NULL;
        $edit_function        = (isset($edit_function)) ? $edit_function : NULL;
        $delete_function    = (isset($delete_function)) ? $delete_function : NULL;
        $item_id        =  (isset($item_id)) ? $item_id : NULL;
        $comment_id        = (isset($comment_id)) ? $comment_id : NULL;
            
        if(($user_data['logged_in']) && ($user_data['admin']))
        {
            //if the approval_function is set, draw the approve link
            if (($approval_function) && ($item_id))
            {
                echo "<a href='link to controller approve function'>approve</a>";
            }
            
            //if the edit_function is set, draw the edit link
            if (($edit_function) && ($item_id))
            {
                echo "<a href='link to controller edit function'>edit</a>";
            }
            
            //if the delete_function is set, draw the delete link            
            if (($delete_function) && ($item_id))
            {
                echo "<a href='link to controller delete function'>delete</a>";
            }
        }
                    
        //reset the variables so other instances of this view don't "remember" them.
        $author            = NULL;
        $controller        = NULL;
        $approval_function    = NULL;
        $edit_function        = NULL;
        $delete_function    = NULL;
        $item_id        = NULL;
        $comment_id        = NULL;
    ?&gt;
</div>

so what I wanted was that in a view, they would only have to set the array variables for the items they cared about (ie, comments don't need to set the 'approval_function', and blogs don't need to set the 'comment_id'). comments don't need to be approved, so the approve link shouldn't be drawn above each comment, but when I run this code as shown here, the approve link is drawn for the comments (because the blog admin tools is rendered first, i think) and the only way to get rid of it is to explicitly add
Code:
'approval_function' => NULL,
in the array definition.

This means if I add more to the admin_tools view, then I have to go change every place that uses it, rather than just add the places that use the new parts of it.
#2

[eluser]bretticus[/eluser]
Not exactly sure what you have here because the way you seem to be doing this is a little unorthodox. It looks like you are loading views from a view in a loop??? I think it's fair to warn you that each one of those calls eventually calls include which may be a lot of unnecessary overhead. The idea of views in MVC is to separate layout generation from controller logic as much as possible. I suppose this is what you mean by "inline." Don't get me wrong, I'm sure this solves a problem of organization for you, it may just be a bit too much when you have a lot of comments or posts. It might be better to generate all the data in the controller and pass it once with the sub view iterating the data to build comment divs, etc. You could avoid passing the admin data from the controller if not in admin mode also. Then you wouldn't have all that extra complexity in your views.
#3

[eluser]vecima[/eluser]
I agree as far as sending data from the controller would be better, and it would be best NOT to call load->view() in a loop... I was just looking for a way to maintain the code for the admin controls in one place, and use it in several.

In the end, since there are a few kinds of blogs, but they all use the same comments view for comments, I may just put the view data into the comment, and only use this separate "admin_tools" view for the blogs.




Theme © iAndrew 2016 - Forum software by © MyBB