【问题标题】:Internal Link News: excludeAlreadyDisplayedNews内部链接新闻:excludeAlreadyDisplayedNews
【发布时间】:2019-04-06 18:31:50
【问题描述】:

我使用的是内部链接新闻,这意味着我使用标准页面作为新闻页面。在这些页面上,我有一个新闻滑块来显示其他新闻。在这里我需要选项: excludeAlreadyDisplayedNews 从新闻中删除当前页面。

但是如何在标准页面上添加<n:excludeDisplayedNews newsItem="{newsItem}"/>? 是否有用于加载此页面的相关 newsItem 的打字稿?也许数据处理器可以做到这一点,但我不知道怎么做?

另一个想法是向页面添加一个附加字段,因此用户将新闻记录添加到页面。这是多点击一次,OK,但是在将新闻UID传递给viewhelper时,我得到了这个错误信息:

The argument "newsItem" was registered with type "GeorgRinger\News\Domain\Model\News", but is of type "integer" in view helper "GeorgRinger\News\ViewHelpers\ExcludeDisplayedNewsViewHelper".

任何帮助表示赞赏:)

【问题讨论】:

    标签: typo3 typo3-8.x tx-news


    【解决方案1】:

    这是完整的解决方案:

    1. 编写DataProcessor获取相关新闻记录
    2. 添加 NewsDataProcessor
    3. 将 n:excludeDisplayedNews 添加到流体模板

    第 1 步:在您的 Page Typoscript 中,添加一个 DataProcessor 以获取相关的新闻记录。将此添加到页面 FLUIDTEMPLATE Typoscript 的 dataProcession 块中:

    10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
    10 {
        table = tx_news_domain_model_news
        #pid for news folder
        pidInList = 123
        where.data = page : uid
        where.wrap = internalurl=|
        as = displayedNews
        dataProcessing {
            10 = MyCompany\MyExtension\DataProcessor\NewsDataProcessor
            10 {
                field = uid
            }
        }
    }
    

    注意:internalUrl 是一个字符串。对我来说,它是这样工作的,但可能需要拼写链接语法。欢迎任何查询改进!

    第 2 步:在 MyExtension/Classes/DataProcessor/NewsDataProcessor.php 中添加 NewsDataProcessor

    <?php
    namespace MyCompany\MyExtension\DataProcessor;
    
    use GeorgRinger\News\Domain\Repository\NewsRepository;
    use TYPO3\CMS\Core\Utility\GeneralUtility;
    use TYPO3\CMS\Extbase\Object\ObjectManager;
    use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
    use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
    
    class NewsDataProcessor implements DataProcessorInterface
    {
        /**
         * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj
         * @param array $contentObjectConfiguration
         * @param array $processorConfiguration
         * @param array $processedData
         * @return array
         */
        public function process(
            ContentObjectRenderer $cObj,
            array $contentObjectConfiguration,
            array $processorConfiguration,
            array $processedData
        ) {
    
            /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
            $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
            /** @var \GeorgRinger\News\Domain\Repository\NewsRepository $newsRepository */
            $newsRepository = $objectManager->get(NewsRepository::class);
    
            $field = 'uid';
            if (array_key_exists('field',$processorConfiguration)) {
                $field = $processorConfiguration['field'];
            }
    
            $newsArray = $processedData['data'];
            $news = $newsRepository->findByUid((int)$newsArray[$field], false);
    
            $processedData['news'] = $news;
            return $processedData;
        }
    }
    

    在以后的 EXT:news 版本(当前为 7.0.7)中,可能会有一个 DataProcessor 可用,那么您可以跳过这一步并使用现有的一个

    第 3 步:将 n:excludeDisplayedNews Viewhelper 添加到页面的流体模板中。不要忘记将 Viewhelper 命名空间添加到模板中。

    <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:n="http://typo3.org/ns/GeorgRinger/News/ViewHelpers"
      data-namespace-typo3-fluid="true">
    
    <f:layout name="MyLayout"/>
    
    <f:section name="main">
        <f:for each="{displayedNews}" as="newsItem">
            <n:excludeDisplayedNews newsItem="{newsItem.news}" />
        </f:for>
        <div class="main-content">
            ...
        </div>
    </f:section>
    
    </html>
    

    【讨论】:

      【解决方案2】:

      我认为没有一种简单、干净的方法可以做到这一点。该页面不是实际的新闻记录,因此从技术上讲它不会显示。我可以想到 3 种可能的解决方案:


      实际上在页面上显示新闻记录,使用一个空模板(n:excludeDisplayedNews ViewHelper 除外)因此它不显示任何内容。我不确定这是否适用于“内部链接”新闻项目,但如果可以,这是最简单的方法。

      您可以使用以下 TypoScript 执行此操作:

      lib.displayedNews = USER
      lib.displayedNews {
        userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
        extensionName = News
        pluginName = Pi1
        vendorName = GeorgRinger
        switchableControllerActions {
          News {
            1 = detail
          }
        }
      
        views =< plugin.tx_news.view
        view {
          templateRootPaths.200 = path/to/template/with/only/excludeDisplayedNews/
        }
        settings =< plugin.tx_news.settings
        settings {
          singleNews.current = 1
          useStdWrap = singleNews
          insertRecord = 1
        }
      }
      

      在您的页面模板中,您可以使用:

      <f:for each="{displayedNews}" as="newsItem">
          <f:cObject typoscriptObjectPath="lib.displayedNews" data="{newsItem.data.uid}" />
      </f:for>
      

      而您的 News/Detail.html 模板将是:

      <n:excludeDisplayedNews newsItem="{newsItem.uid}" />
      

      使用自定义 ViewHelper 或 DataProcessor 获取新闻记录对象,以便您可以将其填充到 n:excludeDisplayedNews ViewHelper 中。在我看来,这是最干净的解决方案,但也需要最多的工作。


      创建一个用户函数来填充新闻扩展用来跟踪显示的新闻记录的全局数组,例如:$GLOBALS['EXT']['news']['alreadyDisplayed'][$newsUid] = $newsUid;

      【讨论】:

      • 非常感谢您的所有意见!我尝试了其中的一些,现在实现了 DataProcessor 解决方案。它可以解决问题,并且应该可以重复用于未来的各种新闻问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      相关资源
      最近更新 更多