0

我如何缓存(使用 ModX 的 cacheManager),我在这里生成的动态占位符:

// recursive function to generate our un-ordered list of menu items
if(!function_exists('GenerateMenu')){
    function GenerateMenu($level, $parent = 0, $wc, $wi, $we, $cs, $sc, $cl){
        try {
            $lvl = ++$level;
            global $modx;
            // Check for #1, should this be cached, #2 does it already exist in the cache
            $cached = $modx->cacheManager->get('Navigator');
            if($sc && isset($cached)){
                // need to get the placeholders from cache - here somehow!
                return $cached;
            }else{
                // get the site start
                $siteStartId = $modx->getOption('site_start');
                // Set our initial rows array
                $rows = array();
                // Run our query to get our menu items
                $sql = 'Select `id`, `menutitle`, `uri`, `longtitle`, `parent`, `link_attributes`, `class_key`, `content`, `alias`, `introtext`
                                    From `' . $modx->getOption(xPDO::OPT_TABLE_PREFIX) . 'site_content` 
                                    Where `deleted` = 0 AND `hidemenu` = 0 AND `published` = 1 AND `parent` = :parent
                                    Order by `parent`, `menuindex`';
                $query = new xPDOCriteria($modx, $sql, array(':parent' => $parent));
                if ($query->stmt && $query->stmt->execute()) {
                    $rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
                }
                // do some cleanup
                unset($query, $sql);
                // make sure we have some rows, and then build our html for the menu
                if($rows){
                    // grab a count of our results
                    $rCt = count($rows);
                    $cls = ($lvl > 1) ? 'sub-item-' . $lvl : 'main-item-' . $lvl;
                    $ret .= '   <ul class="' . $cls . '" id="' . $cls . '-' . $parent . '">' . "\r\n";
                    for($i = 0; $i < $rCt; ++$i){
                        // if this resource is a WebLink, show the content in it, as the URL for the href tag, otherwise, use the resource's URI
                        $url = ($rows[$i]['class_key'] == 'modWebLink') ? $rows[$i]['content'] : '/' . $rows[$i]['uri'];
                        // Check for the site's start id, if true, show a "blank" link, otherwise show the $url
                        $showUrl = ($siteStartId == $rows[$i]['id']) ? '/' : $url;
                        $la = (strlen($rows[$i]['link_attributes']) > 0) ? ' ' . $rows[$i]['link_attributes'] : null;
                        // Set some dynamic placeholders, they can only be used ont he pages that contain this snippet
                        $modx->toPlaceholders(array('Title-' . $rows[$i]['id'] => $rows[$i]['longtitle'],
                                                    'MenuTitle-' . $rows[$i]['id'] => $rows[$i]['menutitle'],
                                                    'URL-' . $rows[$i]['id'] => $showUrl), 
                                                'link');
                        $ret .= '       <li class="' . $cls . '" id="' . $rows[$i]['alias'] . '">' . "\r\n";
                        $ret .= '           <a href="' . $showUrl . '" title="' . $rows[$i]['longtitle'] . '"' . $la . '>' . $rows[$i]['menutitle'] . '</a>' . "\r\n";
                        $ret .= GenerateMenu($lvl, $rows[$i]['id']);
                        // Check for a snippet, and render it
                        $it = $rows[$i]['introtext'];
                        if($cs && IsSnippet($it)){
                            // if we find a snippet in the Summary field, run it, and attach it to our output   
                            preg_match('/\[\[!?(.*)\]\]/', $it, $sm);
                            $ret .= $modx->runSnippet($sm[1]);
                            // clean up
                            unset($sm);
                        }
                        $ret .= '       </li>' . "\r\n";
                    }
                    $ret .= '   </ul>' . "\r\n";
                }
                // clean up
                unset($rows);           
                // Check to see if we should cache it, if so, set it to cache, and apply the length of time it should be cached for: defaults to 2 hours
                if($sc){
                    // NEED TO SET THE PLACEHOLDERS TO CACHE SOMEHOW
                    $modx->cacheManager->set('Navigator', $ret, $cl);
                }
                // return the menu
                return $ret;
            }
        } catch(Exception $e) {
            // If there was an error, make sure to write it out to the modX Error Log
            $modx->log(modX::LOG_LEVEL_ERROR, '[Navigator] Error: ' . $e->getMessage());
            return null;
        }
    }
}
4

2 回答 2

1

移动toPlaceholders()到脚本的末尾,而是缓存占位符数据数组:

// attempt to retrieve placeholders from cache
$placeholders = $modx->cacheManager->get('Navigator');

// if not in cache, run your snippet logic and generate the data
if (empty($placeholders))) {
    $placeholders = array(
        'myplaceholder' => 'placeholder data'
    );
    $modx->cacheManager->set('Navigator', $placeholders, $cl);
}

// set placeholders for use by MODX
$modx->toPlaceholders($placeholders);
于 2014-01-06T22:55:34.600 回答
1

最简单的解决方案可能是 pdoTools,它允许您在运行时建立缓存。

http://www.shawnwilkerson.com/modx/tags/pdotools/

此外,我不相信资源占位符被缓存,这是让您的项目缓存的最佳位置:

            case '+':
                $tagName= substr($tagName, 1 + $tokenOffset);
                $element= new modPlaceholderTag($this->modx);
                $element->set('name', $tagName);
                $element->setTag($outerTag);
                $elementOutput= $element->process($tagPropString);
                break;

从https://github.com/modxcms/revolution/blob/master/core/model/modx/modparser.class.php#L455的第 455-461 行

您可能会注意到其他标签类型具有:

$element->setCacheable($cacheable);

我在本书的附录 D 中介绍了解析器。我在 2011 年发现了 Jason 纠正的一些问题。

于 2015-08-09T21:50:19.710 回答