SemicolonAcademy / ci-cms

Automatically exported from code.google.com/p/ci-cms
Other
0 stars 0 forks source link

Multiple Menus #48

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I may be using the Navigation class incorrectly. However, the only way I see to 
have multiple menus in the system is to create a disabled parent and then pass 
the parent id to the print_menu() method. This becomes an issue if you develop 
on multiple machines as I do where the actual record id may be different from 
one db to another. I develop on a local host and then move things to the 
server. Unless the server db is an exact replica of the development db, the ids 
don't always match.

I think it would be better if we allowed users to gain access to the menu item 
id via a method call where we look up the menu item by title. That way the user 
could define disabled place holders like "Top-Menu" and "Footer-Menu" and then 
print the menu doing something like: 

echo $this->navigation->print_menu($this->navigation->findId('Top-Menu'));
echo $this->navigation->print_menu($this->navigation->findId('Footer-Menu'));

If you like this idea the following code added to the navigation library would 
do the job:

        /**
         * Given a menu item's title
         * Or an array of field/value pairs
                 * Return it's record id
         */
        function findId($params=array())
        {
            $result = 0;

            // do we have an array of fields?
            if(!empty($params)&& is_array($params))
            {
                foreach($params as $f => $v)
                {
                    $this->obj->db->where($f, $v);  
                }
            }
            // Assume title
            elseif(!empty($params) && is_string($params))
            {
                $this->obj->db->where('title', $params);
            }
            else
            {
                return $result;     
            }
            // Insure we only return one record
            $this->obj->db->limit(1);
            $query = $this->obj->db->get('navigation');

            foreach($query->result() as $row)
            {
                $result = $row->id;
            }

            return $result;

        }

Finally, we could just wrap the above call in a method like: 
$this->navigation->print_named_menu($title);

This way the user doesn't need to know the id. 

Original issue reported on code.google.com by rmorga...@gmail.com on 13 Oct 2010 at 10:06

GoogleCodeExporter commented 9 years ago
I think you are right.
But that's why I never print menu by id. If you check the header.php in the 
default template, you can see how I build menus by parent name.

So I create parent menus like "topmenu", "leftmenu" etc.

Then to get the menu structure I do

{{
$navs = $this->navigation->get(array('title' => 'topmenu', 'lang' => 
$this->user->lang))
}}

So I get the menu by title.

Maybe instead of doing twice the query (i.e. findID first then print by ID), it 
is better to create a function print_menu_by_title($title)

What do you think?

Original comment by heriniai...@gmail.com on 13 Oct 2010 at 10:16

GoogleCodeExporter commented 9 years ago
That could easily be done. I'll work it up for you.

Original comment by rmorga...@gmail.com on 13 Oct 2010 at 10:26

GoogleCodeExporter commented 9 years ago
Here are the methods I worked out for named menus:

Use: echo $this->navigation->print_menu_by_title('Footer-Menu');

Code (Add to the Navigation library): 

        function print_menu_by_title($title='')
        {
            //echo  "Parent Id: ".$parent;

            if (!$data = $this->obj->cache->get('navigation'.$title.$this->obj->user->lang, 'navigation'))
            {
                $data = $this->_print_menu_by_title($title);
                $this->obj->cache->save('navigation'.$title.$this->obj->user->lang, $data, 'navigation',0 );
            }
            return $data;
        }

        function _print_menu_by_title($title='')
        {
            $select = "SELECT t1.* "
                    ."FROM `ci_navigation` t1 "
                    ."JOIN `ci_navigation` t2 ON t1.parent_id = t2.id "
                    ."WHERE t2.title = '$title '"
                    ."AND t1.active = 1 "
                    ."AND t2.lang = '".$this->obj->user->lang."' "
                    ."AND t1.lang = '".$this->obj->user->lang."' "
                    ."AND t2.g_id IN ('".join("', '", $this->obj->user->groups)."') "
                    ."AND t1.g_id IN ('".join("', '", $this->obj->user->groups)."') "
                    ."ORDER BY t1.parent_id, t1.weight";

            $query = $this->obj->db->query($select);        

            if ($query->num_rows() == 0)
            {
                return false;
            }
            $html = '<ul ' . (($this->nav_opened == false) ? 'class="nav"' : '') . '>';
            $this->nav_opened = true;
            foreach ($query->result_array() as $item)
            {
                $html .= '<li ' . ($item['uri'] == substr($this->obj->uri->uri_string(), 1) ? 'class="current" ' : '') . '>';
                $html .= '<a href="'. $this->fix_uri($item['uri']) .'">'.$item['title'].'</a>';
                // calling same function where we are (recursive) to check if menu item has submenu
                $html .= $this->_print_menu($item['id']);
                $html .= '</li>';
            }

            $html .= '</ul>';
            return $html;
        }       

Original comment by rmorga...@gmail.com on 13 Oct 2010 at 11:38

GoogleCodeExporter commented 9 years ago
Here are the methods I worked out for named menus:

Use: echo $this->navigation->print_menu_by_title('Footer-Menu');

Code (Add to the Navigation library): 

        function print_menu_by_title($title='')
        {
            //echo  "Parent Id: ".$parent;

            if (!$data = $this->obj->cache->get('navigation'.$title.$this->obj->user->lang, 'navigation'))
            {
                $data = $this->_print_menu_by_title($title);
                $this->obj->cache->save('navigation'.$title.$this->obj->user->lang, $data, 'navigation',0 );
            }
            return $data;
        }

        function _print_menu_by_title($title='')
        {
            $select = "SELECT t1.* "
                    ."FROM `ci_navigation` t1 "
                    ."JOIN `ci_navigation` t2 ON t1.parent_id = t2.id "
                    ."WHERE t2.title = '$title '"
                    ."AND t1.active = 1 "
                    ."AND t2.lang = '".$this->obj->user->lang."' "
                    ."AND t1.lang = '".$this->obj->user->lang."' "
                    ."AND t2.g_id IN ('".join("', '", $this->obj->user->groups)."') "
                    ."AND t1.g_id IN ('".join("', '", $this->obj->user->groups)."') "
                    ."ORDER BY t1.parent_id, t1.weight";

            $query = $this->obj->db->query($select);        

            if ($query->num_rows() == 0)
            {
                return false;
            }
            $html = '<ul ' . (($this->nav_opened == false) ? 'class="nav"' : '') . '>';
            $this->nav_opened = true;
            foreach ($query->result_array() as $item)
            {
                $html .= '<li ' . ($item['uri'] == substr($this->obj->uri->uri_string(), 1) ? 'class="current" ' : '') . '>';
                $html .= '<a href="'. $this->fix_uri($item['uri']) .'">'.$item['title'].'</a>';
                // calling same function where we are (recursive) to check if menu item has submenu
                $html .= $this->_print_menu($item['id']);
                $html .= '</li>';
            }

            $html .= '</ul>';
            return $html;
        }       

Original comment by rmorga...@gmail.com on 13 Oct 2010 at 11:42