猜猜我的问题与这个问题密切相关:Snippet duplicates content when used multiple times on page
我的问题的要素如下......
$ modx-> loadedResources :通过页面加载时的片段在主$ modx对象中注册的(空)数组。该数组随机保存从数据库中提取的资源的资源ID,因此相同的资源不会在同一页面上显示两次。
loadRandomResource :使用XPDO样式查询从数据库加载随机资源的代码段。它使用$modx->parseChunk()
用资源数据填充块中的占位符。每次调用时,它会将获取的获取资源的id附加到$modx->loadResources
数组。
我使用了一些调试来检查资源id是否正确存储在我的数组中,每次我获取一个新的随机资源时都是如此。然后,我检查db是否返回不同的结果,每次调用loadRandomResource片段时都是如此。我还可以确认它没有返回重复的结果(我在XPDO查询中排除了已经加载的资源ID)。
但是,当我在整个页面模板中的3个不同位置调用代码段时,所有3个代码段调用都会呈现相同的资源,这很奇怪,因为我的调试显示正在从数据库加载唯一数据,并被发送到用于渲染的块。
请在下面找到代码段以及大块标记。 有没有人有任何想法?非常感谢任何帮助!
loadRandomResource代码段
$criteria = $modx->newQuery('modResource');
$criteria->select(array('id','pagetitle'));
$criteria->sortby('RAND()');
$criteria->limit(1);
$whereOptions = array(
'parent' => 2,
'deleted' => false,
'hidemenu' => false,
'published' => true
);
if (!empty($modx->loadedResources)) {
$whereOptions['id:NOT IN'] = $modx->loadedResources;
}
$criteria->where($whereOptions);
$resources = $modx->getCollection('modResource', $criteria);
$output = '';
foreach ($resources as $resource) {
$fields = $resource->toArray();
$fields['tv.tvPersonalPicture'] = $resource->getTVValue('tvPersonalPicture');
$fields['tv.tvJobTitle'] = $resource->getTVValue('tvJobTitle');
$output .= $modx->parseChunk('cnkTeamListItem', $fields);
$modx->loadedResources[] = $fields['id'];
}
return $output;
cnkTeamListItem chunk
<div>
<img src="[[+tv.tvPersonalPicture]]" alt="[[+pagetitle]]" />
<h2>[[+pagetitle]]<br /><span>[[+tv.tvJobTitle]]</span></h2>
</div>
答案 0 :(得分:3)
我自己找到了答案,虽然解决方案有点奇怪......
我在我的模板中调用了我的自定义代码段3次,未缓存。每个电话虽然看起来一模一样......
[[!loadRandomResource? &type='teammember']]
即使我有感叹号,仍然是ModX在相同的页面请求中缓存了这个电话。
因此,当我为3个调用中的每个调用添加一个随机唯一值时,问题就解决了。
致电1:[[!loadRandomResource? &type='teammember' &unique='123465']]
致电2:[[!loadRandomResource? &type='teammember' &unique='987654']]
致电1:[[!loadRandomResource? &type='teammember' &unique='666666']]
不知道这是一个错误还是一个功能,但我认为感叹号阻止了缓存,无论是在不同的网页浏览中,还是在同一页面视图中。无论如何,请求帮助。
答案 1 :(得分:0)
我使用此代码在snippents中渲染块:
<?php
// get chunk or template
$tplRow = $modx->getOption('tplRow', $scriptProperties, '');
// get template
if (substr($tplRow, 0, 6) == "@CODE:") {
$tplRow = substr($tplRow, 6);
} elseif ($chunk = $modx->getObject('modChunk', array('name' => $tplRow), true)) {
$tplRow = $chunk->getContent();
} else {
$tplRow = false;
}
// render template
$field = array(); // your fields
if ($tplRow) {
$chunk = $modx->newObject('modChunk');
$chunk->setCacheable(false);
$chunk->setContent($tplRow);
$output[]= $chunk->process($fields);
} else {
$output[]= '<pre>' . print_r($fields, 1) . '</pre>';
}
答案 2 :(得分:0)
你确实意识到你可以用getResources做到这一点,不是吗?
http://rtfm.modx.com/display/ADDON/getResources
&sortby=`RAND()`&limit=`1`