I did this for the page manager in PyroCMS, but this is not an easy task.
Each page has its own slug and parent_id, and then, to read the correct page, it goes through each of the page pools and attaches a child element. He knows how many children they have, if there are 5 children, he chooses the 5th table of his own.
Here is a sample code:
public function get_by_path($segments = array()) { // If the URI has been passed as a string, explode to create an array of segments if(is_string($segments)) { $segments = explode('/', $segments); } // Work out how many segments there are $total_segments = count($segments); // Which is the target alias (the final page in the tree) $target_alias = 'p'.$total_segments; // Start Query, Select (*) from Target Alias, from Pages $this->db->select($target_alias.'.*'); $this->db->from('pages p1'); // Loop thorugh each Slug $level = 1; foreach( $segments as $segment ) { // Current is the current page, child is the next page to join on. $current_alias = 'p'.$level; $child_alias = 'p'.($level - 1); // We dont want to join the first page again if($level != 1) { $this->db->join('pages '.$current_alias, $current_alias.'.parent_id = '.$child_alias.'.id'); } // Add slug to where clause to keep us on the right tree $this->db->where($current_alias . '.slug', $segment); // Increment ++$level; } // Can only be one result $this->db->limit(1); return $this->db->get()->row(); }
A little nuts, but it works great. This can be very slow, so PyroCMS also maintains a lookup table in which the id and page URIs will quickly match.
Here you can see the whole model:
http://github.com/philsturgeon/pyrocms/blob/master/application/modules/core/pages/models/pages_m.php
source share