fab/vidi-frontend

前端通用列表组件,可以以高级方式过滤内容... 来了,看到了,征服了!

安装次数: 2,441

依赖项: 0

建议者: 0

安全: 0

星星: 6

关注者: 3

分支: 5

语言:JavaScript

类型:typo3-cms-extension

5.0.10 2023-03-23 10:38 UTC

README

通用列表组件,可以以高级方式过滤内容... 来了,看到了,征服了!本扩展基于 Vidi,在后端提供类似的功能集。

安装后,可以在后端插件记录中配置要渲染的内容类型,并关联自定义模板。在前端,我们使用优秀的 DataTables,这是一个智能且快速排序和过滤数据的jQuery插件。过滤器条由 Visual Search jQuery插件提供,它提供了很好的分面能力和直观的搜索。

实时示例 http://www.washinhcf.org/resources/publications/

兼容性和维护

此包目前正在以下版本上维护

项目信息和版本

稳定版本: https://extensions.typo3.org/extension/vidi_frontend/

开发版本: https://github.com/fabarea/vidi_frontend

git clone https://github.com/fabarea/vidi_frontend.git

有关最新开发的新闻也发布在 http://twitter.com/fudriot

安装和需求

首选方式是使用Composer安装扩展,如下所示

composer require fab/vidi-frontend

# -> next step is to open the BE and activate the extension in the Extension Manager.

你几乎完成了!在 General Plugin > Generic List Component 中创建一个类型为 "Vidi Frontend" 的内容元素,并按需配置。

基于模板的显示

从Vidi Frontend 1.3开始,可以配置自定义模板来显示记录。我们可以通过TypoScript注册新模板。

plugin.tx_vidifrontend {
		settings {

		# Used in plugin "Generic List - with template
		listTemplates {
		
			# We disable existing template for demo purposes
			1 >
			
			# Best is to use a key as of 100 to not override existing configuration
			# Tip: get inspired by EXT:vidi_frontend/Resources/Private/Standalone/DemoTemplateList.html
			100 {
                label = My specila list
                path = EXT:my_extension/Resources/Private/Standalone/MyList.html
                additionalSettingsHelp (
                     # We can add additional settings tip for the BE user.
                     # The settings will be passed to list view.
                )
            }
		}
	}
}

开始编辑模板文件 EXT:my_extension/Resources/Private/Standalone/MyList.html

路由增强器

对于TYPO3 v9,需要添加到 /config/sites/[SITE_IDENTIFIER]/config.yml

routeEnhancers:
  VidiFrontend:
    type: Plugin
    # limitToPages: [12]
    routePath: '/content/{action}/{contentElement}-{content}'
    namespace: 'tx_vidifrontend_pi1'
    defaults:
      action: "show"
    requirements:
      content: '[0-9].*'
      contentElement: '[0-9].*'

配置

该插件可以在多个地方进行配置,如TypoScript、PHP或插件记录本身。

重要 默认情况下,为Bootstrap加载了CSS + JS文件。对于更Vanilla的口味,编辑TypoScript中的settings键中的path,并加载您自己的正确资产。以下是一些注释:

#############################
# plugin.tx_vidifrontend
#############################
plugin.tx_vidifrontend {

    settings {

        asset {

            vidiCss {
                # For none Bootstrap replace "vidi_frontend.bootstrap.min.css" by "vidi_frontend.min.css"
                path = EXT:vidi_frontend/Resources/Public/Build/StyleSheets/vidi_frontend.bootstrap.min.css
                type = css
            }

            vidiJs {
                # For none Bootstrap replace "vidi_frontend.bootstrap.min.js" by "vidi_frontend.min.js"
                path = EXT:vidi_frontend/Resources/Public/Build/JavaScript/vidi_frontend.bootstrap.min.js
                type = js
            }
        }
    }
}

自定义网格渲染器

假设我们想要对列进行完全自定义的输出,我们可以通过实现网格渲染来实现。以下是一个针对表fe_users的示例。我们首先必须在某个Configuration/TCA/Override/fe_users.php中注册新列。

$tca = [
    'grid_frontend' => [
        'columns' => [

            # The key is totally free here. However we prefix with "__" to distinguish between a "regular" column associated to a field.
            '__my_custom_column' => [
                'renderers' => array(
                    'Vendor\MyExt\Grid\MyColumnRenderer',
                ),
                'sorting' => FALSE,
                'sortable' => FALSE,
                'label' => '',
            ],
        ],
    ],
];

\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA']['fe_users'], $tca);

要放置在EXT:MyExt/Classes/Grid/MyColumnRenderer中的相应类

namespace Vendor\MyExt\Grid;

/**
 * Class to render a custom output.
 */
class MyColumnRenderer extends Fab\Vidi\Grid\ColumnRendererAbstract {

    /**
     * Render a publication.
     *
     * @return string
     */
    public function render() {
        return $output;
}

调整列配置

列配置来自TCA。有时我们需要调整其配置以适应前端,我们可以简单地丰富它。最好的方法是学习示例并从EXT:vidi_frontend/Configuration/TCA/fe_users.php中获取灵感

$tca = array(
    'grid_frontend' => array(
        'columns' => array(

            # Custom fields for the FE goes here
            'title' => [],
        ),
    ),
);

自定义分面

在视觉搜索中可见的方面可以通过标准进行搜索。方面通常映射到一个字段,但不是强制的;它可以是任意值。要提供自定义方面,必须实现接口\Fab\Vidi\Facet\FacetInterface。最佳做法是借鉴\Fab\Vidi\Facet\StandardFacet并提供自己的实现。

$tca = [
    'grid_frontend' => [
        'facets' => [
            new \Vendor\MyExt\Facets\MyCustomFacet(),
        ],
    ],
];

\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA']['fe_users'], $tca);

关联类

<?php
namespace Vendor\MyExt\Facets;


use Fab\Vidi\Facet\FacetInterface;
use Fab\Vidi\Facet\StandardFacet;
use Fab\Vidi\Persistence\Matcher;

/**
 * Class for configuring a custom Facet item.
 */
class CategoryPublicationFacet implements FacetInterface
{

    /**
     * @var string
     */
    protected $name = '__categories_publications';

    /**
     * @var string
     */
    protected $label = 'Categories';

    /**
     * @var array
     */
    protected $suggestions = [];

    /**
     * @var string
     */
    protected $fieldNameAndPath = 'metadata.categories';

    /**
     * @var string
     */
    protected $dataType;

    /**
     * @var string
     */
    protected $canModifyMatcher = true;


    /**
     * Constructor of a Generic Facet in Vidi.
     *
     * @param string $name
     * @param string $label
     * @param array $suggestions
     * @param string $fieldNameAndPath
     */
    public function __construct($name = '', $label = '', array $suggestions = [], $fieldNameAndPath = '')
    {
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @return string
     */
    public function getLabel()
    {
        return $this->label;
    }

    /**
     * @return array
     */
    public function getSuggestions()
    {

        return [1 => 'foo', 2 => 'bar', ];
    }

    /**
     * @return bool
     */
    public function hasSuggestions()
    {
        return true;
    }

    /**
     * @return string
     */
    public function getFieldNameAndPath()
    {
        return $this->fieldNameAndPath;
    }

    /**
     * @param string $dataType
     * @return $this
     */
    public function setDataType($dataType)
    {
        $this->dataType = $dataType;
        return $this;
    }

    /**
     * @return bool
     */
    public function canModifyMatcher()
    {
        return $this->canModifyMatcher;
    }

    /**
     * @param Matcher $matcher
     * @param $value
     * @return Matcher
     */
    public function modifyMatcher(Matcher $matcher, $value)
    {
        if (MathUtility::canBeInterpretedAsInteger($value)) {
            $matcher->equals('metadata.categories', $value);
        } else {
            $matcher->like('metadata.categories', $value);
        }
        return $matcher;
    }

    /**
     * Magic method implementation for retrieving state.
     *
     * @param array $states
     * @return StandardFacet
     */
    static public function __set_state($states)
    {
        return new CategoryPublicationFacet($states['name'], $states['label'], $states['suggestions'], $states['fieldNameAndPath']);
    }
}

注册新模板

内容的详细视图可以根据插件记录进行个性化。要注册更多模板,只需在您的TypoScript配置中定义它们。此TypoScript通常位于EXT:foo/Configuration/TypoScript/setup.txt下。

plugin.tx_vidifrontend {
    settings {
        templates {

            # Key "1", "2" is already taken by this extension.
            # Use key "10", "11" and following for your own templates to be safe.
            10 {
                title = Foo detail view
                path = EXT:foo/Resources/Private/Templates/VidiFrontend/ShowFoo.html
                dataType = fe_users
            }
        }
    }
}

添加自定义约束

如果需要在“低”级别添加额外的自定义约束,可以利用Vidi内容库中的信号槽。要这样做,首先在您的ext_localconf.php文件中注册槽。

$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\SignalSlot\Dispatcher');

$signalSlotDispatcher->connect(
    'Fab\Vidi\Domain\Repository\ContentRepository',
    'postProcessConstraintsObject',
    'Vendor\Extension\Aspects\ProductsAspect',
    'processConstraints',
    true
);

下一步是编写和定制如以下示例所示的PHP类。您可以自由地操作$constraints对象,并根据自己的需要进行个性化。

<?php
namespace Vendor\Extension\Aspects;

use Fab\Vidi\Persistence\Query;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;

/**
 * Class which handle signal slot for Vidi Content controller
 */
class ProductsAspect {

    /**
     * Post-process the constraints object to respect the file mounts.
     *
     * @param Query $query
     * @param ConstraintInterface|null $constraints
     * @param $constraintContainer|null
     * @return array
     */
    public function processConstraints(Query $query, $constraints, $constraintContainer)
    {
        if ($this->isFrontendMode() && $query->getType() === 'tt_products') {

            $additionalConstraints = $query->logicalAnd(
                $query->logicalNot($query->equals('title', '')),
                $query->logicalNot($query->equals('image', ''))
            );

            $constraints = null === $constraints
                ? $additionalConstraints
                : $query->logicalAnd(
                    $constraints,
                    $additionalConstraints
                );
        }
        return [$query, $constraints, $constraintContainer];
    }

    /**
     * Returns whether the current mode is Frontend
     *
     * @return bool
     */
    protected function isFrontendMode()
    {
        return TYPO3_MODE === 'FE';
    }
}

传递动态参数

我们可以传递额外的GET/POST参数,以在网格中动态过滤结果集。一个典型的用例是添加下拉菜单以进行额外的筛选。在这种情况下,参数名称必须看起来像“foo”是字段名。值可以是简单值(等于)或CSV列表,它将被解释为数组(在)。

tx_vididfrontend_pi1[matches][foo]=bar
tx_vididfrontend_pi1[matches][foo]=bar,baz

添加自定义动作

默认情况下,Vidi前端包括一些默认的大规模动作,例如XML、CSV、XLS导出。当然,可以添加自己的动作。这需要两个步骤。第一步是在TCA中声明。

$tca = array(
    'grid_frontend' => [
        'columns' => [
            ...
        ],
        'actions' => [
            \Vendor\MyExt\MassAction\MyAction::class,
        ]
    ],
);

\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA']['tx_domain_model_foo'], $tca);

然后,您需要声明自己的类并实现MassActionInterface,其中有两个主要方法

  • render(),其中组装菜单项的HTML。
  • execute(),其中我们从请求中获取项并根据我们的需求处理它们。execute()方法必须返回一个包含响应以及可能的发送到客户端(浏览器)的头的ResultActionInterface
<?php
namespace Vendor\MyExt\MassAction;


use Fab\VidiFrontend\Service\ContentService;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;


/**
 * Class MyAction
 */
class MyAction extends AbstractMassAction
{

    /**
     * @var string
     */
    protected $name = 'my_action';

    /**
     * @return string
     */
    public function render()
    {
        $result = sprintf('<li><a href="%s" class="export-csv" data-format="csv"><i class="fa fa-file-text-o"></i> %s</a></li>',
            $this->getMassActionUrl(),
            LocalizationUtility::translate('my_action', 'foo')
        );
        return $result;
    }

    /**
     * Return the name of this action..
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Execute the action.
     *
     * @param ContentService $contentService
     * @return ResultActionInterface
     */
    public function execute(ContentService $contentService)
    {
        $result = new JsonResultAction();
        $objects = $contentService->getObjects();

        // Make sure we have something to process...
        if ((bool)$objects) {

            // do something
            ...

            $result->setOuptut('foo')
        }

        return $result;
    }
}

在此基础上,您可能还需要加载自己的JS来捕获动作并在客户端触发必要的动作,例如Ajax请求。

RealURL配置

RealURL配置可以如下所示,以显示漂亮的URL到详细视图。

'postVarSets' => [
    '_DEFAULT' => [
        'content' => [
            ['GETvar' => 'tx_vidifrontend_pi1[contentElement]'],
            ['GETvar' => 'tx_vidifrontend_pi1[action]'],
            ['GETvar' => 'tx_vidifrontend_pi1[content]'],
        ],
    ]
],

在开发中构建资产

该扩展提供了包含所有必要代码的JS/CSS包。如果您需要为这些JS/CSS文件创建新的构建,请考虑BowerGrunt必须作为先决条件安装到您的系统上。

安装所需的Web组件

cd typo3conf/ext/vidi_frontend

# This will populate the directory Resources/Private/BowerComponents.
bower install

# Install the necessary NodeJS package.
npm install

然后,您可以运行扩展的Grunt来生成构建

cd typo3conf/ext/vidi_frontend
grunt build

在开发过程中,您可以使用watch,这样在您编辑文件时就会生成构建

grunt watch

修复VisualSearch

为了改善用户体验,Visual Search插件已被修复,避免下拉菜单意外出现。这意味着在创建新构建时,补丁(目前)必须手动添加。

cd Resources/Private/BowerComponents/visualsearch/
grep -lr "app.searchBox.searchEvent(e)" .

-> There should be 2 occurrences. Comment lines below related to "_.defer".

# Remove assumed already jQuery from dependency
curl http://documentcloud.github.io/visualsearch/vendor/jquery.ui.core.js > Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/jquery.ui.position.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/jquery.ui.widget.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/jquery.ui.menu.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/jquery.ui.autocomplete.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/underscore-1.5.2.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js
curl http://documentcloud.github.io/visualsearch/vendor/backbone-1.1.0.js >> Resources/Private/BowerComponents/visualsearch/build-min/dependencies.js