alnv/catalog-manager-bundle

Contao CMS 的目录管理器 v2


README

注意:不要与 Catalog-Manager v1 一起安装此扩展!

目录管理器(v3)- Contao CMS 的企业级扩展

目录管理器已经在超过 100 个 Contao 项目中得到验证。

亲自体验并安装免费且不受限制的测试版本。只有在项目完成后才购买许可证。在此之前,我们将为您提供支持和咨询服务。

目录管理器的应用领域

  • 范围搜索:快速有效地找到附近的成果。
  • 招聘平台:管理和展示职位空缺和求职申请。
  • 行业名录:为各种行业创建全面的目录和目录。
  • 会员管理:轻松组织和展示成员及其信息。
  • 房地产交易平台:清晰管理和展示房地产信息。
  • 搜索和筛选:使用强大的搜索和筛选功能处理数据。
  • 产品管理:优化组织和展示产品。
  • 收藏夹/愿望列表:为用户提供保存和再次找到收藏品的机会。
  • 多语言支持:支持多种语言,吸引国际观众。

测试目录管理器,并让其在广泛的功能中说服你。我们的团队很乐意在实现你的项目中提供支持。

如何使用

创建目录

您可以在“目录管理器”下轻松创建目录。基本上,一切都是自我解释的。

导航设置

在导航设置中,您只能选择现有的导航点。如果您想添加自己的导航点,您必须在您的 "contao/config/config.php" 中声明。以下是一个例子

use Contao\ArrayUtil;

ArrayUtil::arrayInsert($GLOBALS['BE_MOD'], 1, [
'my_catalogs' => []
]);

这样您就可以创建自己的导航点并自定义目录。别忘了清空 prod.cache ;)

添加子目录

如果您想在目录之间建立父-子关系,只需将子目录作为子点添加到父目录中。这与在页面结构中创建子页面相同。

注意:一旦您的目录包含“数据记录”,您就无法再移动目录了!

字段集和面板

您还可以根据字段集、子面板或类型对目录进行细分。您可以在“编辑面板”(从左数第三个绿色图标)下进行此操作。以下是一些示例配置

使用这些设置,您可以根据需求对目录进行结构化和调整。

按类型设置面板

首先,您需要在您的目录中创建一个名为“type”的输入字段。该字段应承担“type”的角色,并且“type”应在字段名称中。理想情况下,“type”字段作为选择菜单实现,以提供选项选择。为此,定义在选择菜单中应显示的选项。

创建“type”输入字段后,您可以为每个选项创建相应的面板。在面板中,您可以为选择菜单中的每个选项分配一个单独的面板。然后在选择器中选择相应的选项,以显示相应的面板。

如果你没有为 "type" 字段定义标准值,则需要一个默认调色板,在这种情况下作为回退使用。请参阅截图。

角色

在新版本的目录管理器中,你不能直接定义后端 CSS 类、SQL 数据类型或正则表达式。相反,所有操作都通过角色进行,因此为每个字段类型选择合适的角色非常重要。以下是重要角色的概述

  • title: 每个目录都应该有;用于页面标题。
  • alias: 如果你希望有一个别名输入字段(注意:字段名必须为 "alias")。
  • miscellaneous: 二进制字段类型(blob NULL);可用于下拉列表或通用小部件。
  • image: 用于图片。
  • gallery: 用于图片库。
  • file: 用于单个文件。
  • files: 用于多个文件。
  • textfield: varchar(255)…对于无法分配特定角色的所有字段。

从版本 3.2 开始,可以定义自己的角色。

模块列表(FE 模块/内容元素)

列表也是不言自明的。你可以为你的所有目录(一般来说,为所有表格)输出一个列表。唯一困难的是前端数据的输出。与前辈一样,没有后端模块用于前端输出,这意味着你也需要创建一个模板。

与 Catalog Manager v1 相比,这里有两个列表:一个是内容元素,另一个是前端模块。在内容元素中,有一个模板 ce_listview_*,其中所有条目都传递给一个数组。你可以在 foreach 循环中读取这个数组。你可以通过字段名访问字段。

<div class="cm-refrence-list block">
    <?php foreach ($this->entities as $arrEntity): ?>
        <div class="cm-refrence-entity">
            <div class="entity-image">
                <a href="<?= $arrEntity['masterUrl'] ?>">
                    <?php if (!empty($arrEntity['image'])): ?>
                        {{image::<?= $arrEntity['image'][0]['path'] ?>?mode=crop&width=400&height=400}}
                    <?php endif; ?>
                </a>
            </div>
            <div class="entity-content">
                <h3 class="entity-headline"><?= $arrEntity['title'] ?></h3>
                <?php if ($arrEntity['teaser']): ?>
                    <div class="entity-teaser">
                        <p><?= $arrEntity['teaser'] ?></p>
                    </div>
                <?php endif; ?>
            </div>
            <div class="entity-link"><a href="<?= $arrEntity['masterUrl'] ?>">Weiterlesen</a></div>
        </div>
    <?php endforeach;?>
</div>
<?= $this->pagination ?>

使用此模板可以在前端显示您的目录条目。条目将在 foreach 循环中遍历并相应地格式化输出。

前端模块由一个 "wrapper" 模板 mod_listing_table 和各自的条目在单独的模板 cm_listing_* 中输出组成。以下是一个示例

<?php
use Contao\Date;
$arrEvent = $this->getParent();
$strUrl = array_values($arrEvent['pages'])[0]['master'] ?? '';
?>

<div class="cm-event-entity">
    <?php if ($this->origin['startDate']): ?>
    <div class="entity-date">
        <div class="date-day"><p><?= Date::parse('d', $this->origin['startDate']) ?>.</p></div>
        <div class="date-month"><p><?= Date::parse('M', $this->origin['startDate']) ?></p></div>
        <div class="date-year"><p><?= Date::parse('Y', $this->origin['startDate']) ?></p></div>
    </div>
    <?php endif; ?>
    <div class="entity-content">
        <p class="content-location"><?= $this->location ?></p>
        <p class="content-title"><?= $arrEvent['title'] ?></p>
        <?php if ($arrEvent['teaser']): ?>
        <div class="content-teaser">
            <p><?= strip_tags($arrEvent['teaser']) ?></p>
        </div>
        <?php endif; ?>
        <?php if ($strUrl): ?>
        <p class="content-url"><a href="<?= $strUrl ?>?date=<?= $this->id ?>">mehr Erfahren</a></p>
        <?php endif; ?>
    </div>
</div>

在此示例模板中,一个单独的事件条目在前端显示。事件数据通过 Contao 函数格式化并输出。此模板可以根据您网站的需求进行个性化设置。

输出内容元素

如果您在后台模块 "内容元素" 中启用,则可以为每个条目创建单独的内容元素。这些元素不会在模板中默认输出,而是通过一个函数输出

<?= $this->getContentElements() ?>

将此函数添加到您的模板中,以显示内容元素。

愿望单

您的条目可以记录在愿望单中。为此,请在您的模板中添加以下表单

<?php 
    use Alnv\ContaoCatalogManagerBundle\Library\Watchlist;
?>
<?= (new Watchlist())->getForm($this->id, $this->_table, ['useUnits' => true]); ?>

第一个参数必须是数据集的 ID,第二个参数是表。

愿望单的插入标记

{{WATCHLIST}}

返回愿望单中的数据集 ID

{{WATCHLIST-TABLE::?template=ce_watchlist_table&tables=table1,table2}}

返回愿望单中的所有数据集的表

{{WATCHLIST-RESET}}

清空愿望单

{{WATCHLIST-COUNT}}

返回愿望单中的数据集数量

输出子条目

通过 $this->getRelated('myfieldname'),你可以访问子元素。作为返回值,你得到一个数组,你可以通过 foreach 循环遍历并输出。单个数据集再次具有与父元素相同的模板函数。

以下是如何访问它的示例

<?php 
$arrEntities = $this->getRelated('myfieldname');
?>
<?php foreach($arrEntities as $arrEntity): ?>
    <div class="child-entity">
        <h3><?= $arrEntity['title'] ?></h3>
        <p><?= $arrEntity['description'] ?></p>
        <!-- Weitere Felder entsprechend ausgeben -->
    </div>
<?php endforeach; ?>

在此示例中,数组 $arrEntities 通过字段 "myfieldname" 的子元素遍历,并输出每个子元素及其字段,如 "title" 和 "description"。你可以根据需要调整此模式并添加更多字段。

使用 $this->getParent() 可以访问父元素。

网站地图

如果你的条目要出现在网站地图中,你必须确保你的目录在某个前端模块中已选择,并在其中定义一个详细信息页面。

详细信息页面

仅提供前端模块以供详细视图使用。该模块由两个模板组成:mod_master 和 cm_master_。在 cm_master_ 中,规则和函数与列表视图(cm_listing_*)相同。

您可以在同一页面上显示列表和详细视图。使用“元素隐藏”功能来控制列表视图和详细视图的相应模块。请参阅截图。

筛选器

在列表视图中和一些其他模块中,有一个筛选器小部件。请参阅截图。简而言之,您可以在该小部件中输入要筛选的值,可以是“纯文本”或“插入标签”。请注意,实际存储在数据库中的字段值必须与请求的值一致。此外,请注意以下基本运算符

  • 对于数字:等于、小于...
  • 对于多选:REGEXP、FIND_IN_SET

如果您要创建筛选器,则需要一个模块,该模块将筛选参数作为GET参数传递给客户端,例如 https://catalog-manager.org/meine-seite/?category=123。然后您可以使用 {{ACTIVE::category}} 读取“category” GET参数并在筛选器设置中使用它。您可以使用Contao的表单生成器(表单)作为筛选器模块,或者创建自己的表单。

翻译 & 多语言

为了使您的目录(产品、工作、联系人等)多语言化,您可以在目录设置中的数据容器下选择“多语言”选项,并翻译您的表格。我们在这里使用的是 terminal42 的 contao-DC_Multilingual 扩展(https://github.com/terminal42/contao-DC_Multilingual)。

您可以使用 Catalog-Manager 的“翻译”模块翻译选项、下拉列表和字段名称。可用的选项将自动在翻译模块中创建,但最初是禁用的,并且仅在主语言中可用。如果您要使用翻译器,请打开它,选择所需的文本并点击“编辑”。在输入表单中,您可以选择语言和翻译。请参阅截图。

此外,您还可以复制文本并创建一个新的语言。

您还可以创建带有自行选择的字段名的自定义文本。

然后您可以在您的模板中使用这些文本

<?php
use Alnv\ContaoTranslationManagerBundle\Library\Translation;
?>
<div>
    <p><?= Translation::getInstance()->translate('<FELDNAME>') ?></p>
    <p><?= $this->myValue ?></p>
</div>

或使用插入标签

<?php
use Alnv\ContaoTranslationManagerBundle\Library\Translation;
?>
<div>
    <p>{{TRANSLATE::FELDNAME::STANDARD WERT}}</p>
    <p><?= $this->myValue ?></p>
</div>

在模板中输出图片

要配置后端中的图片选择输入字段,请使用“上传”输入字段。然后,您必须选择合适的角色:“image”用于单张图片或“gallery”用于多张图片。无论选择哪个角色,图片都将始终以数组的形式输出,并具有相同的字段名(在数组中)。因此,您需要在模板中使用 FOREACH 循环(或类似的PHP函数)来访问图片

<?php // Beim Upload-Eingabefeld haben wir den Feldname "images" gewählt, daher $this->images ?>
<?php foreach ($this->images as $arrImage): // $this->images "images" ist eine Variable (Feldname im Eingabefeld)  ?>
<figure>
    {{image::<?= $arrImage['path'] ?>?mode=proportional&width=800&height=600}}
    oder
    {{picture::<?= $arrImage['path'] ?>?size=1}}
</figure>
<?php endforeach; ?>

您可以使用插入标签 {{image::}} 或 {{picture::}} 定义图片大小。

JSON 和 AJAX

您也可以通过向以下URL发送POST请求以JSON格式获取前端模块:/catalog-manager/json-listing/<MODULE-ID>/<PAGE-ID>

所需的参数是前端模块(列表视图)的ID和请求来源的页面ID。您可以在URL中附加GET参数,例如 ?category=123。

以下是一个示例

function fetchCatalogData(url) {
    // Markiere den Ladevorgang als aktiv
    this.loading = true;

    // Falls keine URL übergeben wurde, wird eine Standard-URL verwendet
    if (!url) {
        url = '/catalog-manager/json-listing/<MODULE-ID>/<MODULE-ID>';
    }

    // AJAX-POST-Anfrage mit fetch API
    fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams(this.params),
    })
    .then(response => response.json())
    .then(data => {
        // Verarbeite die Antwortdaten
        this.catalogs = this.parse(data.results); // Verarbeitung der Ergebnisse
        this.total = data.limit ? data.limit : 0; // Gesamtzahl der Ergebnisse
        this.pagination = data.pagination; // Pagination-Daten

        // Setze die Pagination nach einer kurzen Verzögerung
        setTimeout(() => {
            this.setPagination(); // Funktion zur Aktualisierung der Pagination
            this.loading = false; // Ladevorgang beenden
            this.initial = false; // Initialisierung beenden
        }, 50);
    })
    .catch(error => {
        console.error('Fehler bei der AJAX-Anfrage:', error);
        this.loading = false; // Ladevorgang beenden
    });
}

使用PHP输出列表

您也可以使用几行PHP代码输出列表。

<?php 

use Alnv\ContaoCatalogManagerBundle\Views\Listing;

$arrEntities = (new Listing('<DEINE-CM-TABELLE>', [
  'column' => ['pid=?'], // Hier kannst du deine Wunschabfrage hinterlegen.
  'value' => [$this->id], // Hier die Datenbankwerte je Abfrage.
  'order' => 'startDate DESC', // Reihenfolge
  'masterPage' => "<SEITEN-ID" // Optional
]))->parse();

<?php foreach ($arrEntities as $arrEntity): ?>
  <h3><?= $arrEntity['MY_FIELD'] ?></h3>
<?php endforeach; ?>

设置圆形搜索

为了正确执行圆形搜索,必须执行以下步骤

1. 在目录中定义地址字段

您的目录需要特定的地址字段,如邮政编码、城市和国家。可选地,也可以添加街道和门牌号。为各个字段分配相应的角色:street(街道)、streetNumber(门牌号)、city(城市)、zip(邮政编码)、postal(邮政编码)、state(州)、country(国家)。

2. 创建GEO-Coding许可证密钥

在Google创建一个GEO-Coding许可证密钥。可以通过以下链接完成:[https://console.cloud.google.com/apis/dashboard](https://console.cloud.google.com/apis/dashboard)

3. 创建包含地址字段的表单

创建一个包含您地址字段的表单

至少包括邮政编码、城市和国家。可选地,可以添加街道和门牌号。使用以下字段名:rs_pstl用于邮政编码,rs_cty用于城市,rs_strt用于街道+门牌号,rs_cntry用于国家,rs_dstnc用于搜索半径定义

在rs_dstnc字段中可以定义搜索半径。这里只接受数字。

v1和v3变更

  • {{CTLG_ACTIVE}} 插入标签将变为 {{ACTIVE}}
  • {{CTLG_MASTER}} 插入标签将变为 {{MASTER}},并且不再需要在页面结构中设置任何设置。
  • {{CTLG_TIMESTAMP}} 将变为 {{TIMESTAMP}},例如 {{TIMESTAMP::tstamp::+ 1 days}}
  • 不再有过滤器表单,而是可以使用表单生成器。
  • 前端编辑不可用(稍后提供)。
  • 修改者不可用(稍后提供)。
  • 范围搜索有了新的字段名
    • rs_pstl将变为postal
    • rs_cty将变为city
    • rs_strt将变为street
    • rs_cntry将变为country
    • rs_dstnc将变为radius

更多信息即将发布…