1

猜猜我的问题与这个问题密切相关:片段在页面上多次使用时会重复内容

我的问题的要素如下...

  1. $modx->loadedResources : 一个(空)数组,通过页面加载时的片段注册在主 $modx 对象中。该数组包含从数据库中随机获取的资源的资源 ID,因此同一资源不会在同一页面上显示两次。

  2. loadRandomResource:使用 XPDO 样式查询从数据库加载随机资源的片段。它用于$modx->parseChunk()用资源数据填充块中的占位符。每次调用时,它都会将要获取的已获取资源的 id 附加到$modx->loadResources数组中。

每次我获取一个新的随机资源时,我都使用了一些调试来检查资源 id 是否正确存储在我的数组中,这恰好是这种情况。然后,我每次调用 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 块

<div>
    <img src="[[+tv.tvPersonalPicture]]" alt="[[+pagetitle]]" />
    <h2>[[+pagetitle]]<br /><span>[[+tv.tvJobTitle]]</span></h2>
</div>
4

3 回答 3

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']]

不知道这是错误还是功能,但我认为感叹号阻止了缓存,无论是跨不同的页面视图,还是在同一页面视图中。无论如何,谢谢你的帮助。

于 2013-06-16T20:10:31.297 回答
0

我使用这段代码在片段中渲染块:

<?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>';
}
于 2013-06-16T18:27:09.633 回答
0

您确实意识到您可以使用 getResources 完成此操作,不是吗?

http://rtfm.modx.com/display/ADDON/getResources

&sortby=`RAND()`&limit=`1`
于 2013-06-21T10:30:12.677 回答