cakephp - php menu generated from a db -
i have database products organized categories , subcategories. thing generate menu querying categories table. because categories same(they can change/add once month or something), don't think have query database each access of web-page. have better idea me?
many thanks!
ps: i'm using cakephp framework, answer/idea doesn't have relate it. find memcache
i think in instance use combination of action caching , view caching. won't go vagaries of different caching engines, basics solve problem.
the first thing need turn caching on. in app/config/core.php, you'll need make couple changes. first, comment out cache.disable line:
//configure::write('cache.disable', true); second, uncomment cache.check line:
configure::write('cache.check', true); finally, you'll need make cachehelper available views, add $helpers member definition in app/app_controller.php:
class appcontroller extends controller { var $helpers = array('cache'); } next, we'll set view element contains category menu (doing view stuff before controller stuff may seem little backwards, bear me -- it'll make sense). putting menu in view element makes caching bit simpler trying selectively designate parts of larger view or layout uncached <cake:no-cache></cake:no-cache> tags.
here's sample view element, rendering category menu in simple unordered list (<ul>):
<?php $menuitems = $this->requestaction(array('controller'=>'categories','action'=>'menu')); echo $html->nestedlist( $menuitems, 'ul' ); ?> you may have been told 1 or more people in past requestaction evil, initiates whole new dispatch. true. should avoid requestaction plague, except when you're doing type of view-caching, in case it's best way go.
we'll store new view element app/views/elements/category_menu.ctp. requestaction invokes menu action in categoriescontroller. here's categoriescontroller looks like, i'll go through bit bit:
class categoriescontroller extends appcontroller { var $cacheaction = array( 'menu/' => '1 day' ); function menu() { return $this->category->find('list', array( 'fields' => array('category.id','category.label'), 'order' => array('category.order') )); } } what does:
- the member definition
$cacheactiontells cake should cache results ofmenuaction 1 day. - the
menumethod returns one-dimensional array of categories, usingcategory.idkeys, ,category.labelvalues.
so, let's go on we've got far. have category_menu element, requests categoriescontroller::menu action. when request received, cake check see whether result of action has been cached, , hasn't expired. if cached result still valid, cake return without invoking menu method defined. otherwise, cake invoke method, , cache result. view element renders result nestedlist.
all remains, then, use view element in other views. here's simple sample app/views/layouts/default.ctp:
<html> [ snip... ] <body> <div class="category-menu"> <?php echo $this->element('category_menu', array('cache'=>'1 day')); ?> </div> <div class="content"> <p>lorem ipsum sit dolor amet.</p> </div> </body </html> we use familiar view::element render category_menu view element created earlier, tell cake want render view element once, cache rendered version, , hold onto month. subsequent requests element, until month elapses or clear cache, deliver pre-rendered view element. won't interpret app/views/elements/category_menu.ctp, less invoke requestaction, or hit database.
to ensure changes make category model records reflected immesiately, can invoke global function clearcache() in create/update actions. 1 caveat clearcache(): it's bit of shotgun approach: inelegant effective. clearcache() wipes out entire cache, rather selectively clearing necessary views. simple approach, however, , given you're talking updating categories monthly, having regenerate cache once month worth diminished hassle of more selective approach.
very long answer! hth
Comments
Post a Comment