x-zolezzi / seo-filter
CakePHP 4 的分页标签过滤插件
dev-main
2023-02-03 15:15 UTC
Requires
- php: >=7.2
- cakephp/cakephp: ~4.1
Requires (Dev)
- phpunit/phpunit: ^8.5 || ^9.3
This package is auto-updated.
Last update: 2024-09-15 14:17:23 UTC
README
CakePHP 4 的分页标签过滤插件
安装
将插件加载到文件 src/Application.php
php bin/cake.php plugin load SeoFilter
使用以下请求创建所需的表
CREATE TABLE IF NOT EXISTS `seofilter_filters` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL, `controller` varchar(255) NOT NULL, `action` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `function_find` varchar(255) NOT NULL, `element` varchar(255) NOT NULL, `titre` varchar(255) DEFAULT NULL, `seo_titre` varchar(255) CHARACTER SET latin1 DEFAULT NULL, `seo_description` varchar(370) CHARACTER SET latin1 DEFAULT NULL, `is_active` tinyint(1) NOT NULL DEFAULT '1', `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `slug` (`slug`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `seofilter_filters_criteres` ( `id` int(11) NOT NULL AUTO_INCREMENT, `seofilter_filter_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `colonne` varchar(255) NOT NULL, `colonne_label` varchar(255) NOT NULL, `function_find_values` varchar(255) NOT NULL, `ordre` tinyint(1) unsigned NOT NULL, `is_active` tinyint(1) NOT NULL DEFAULT '1', `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `seofilter_filter_id_slug` (`seofilter_filter_id`,`slug`), CONSTRAINT `FK_seofilter_filters_criteres_seofilter_filters` FOREIGN KEY (`seofilter_filter_id`) REFERENCES `seofilter_filters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; CREATE TABLE IF NOT EXISTS `seofilter_filters_orders` ( `id` int(11) NOT NULL AUTO_INCREMENT, `seofilter_filter_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `colonne` varchar(255) NOT NULL, `direction` enum('ASC','DESC') NOT NULL, `ordre` tinyint(1) unsigned NOT NULL, `is_active` tinyint(1) NOT NULL DEFAULT '1', `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`) USING BTREE, KEY `seofilter_filter_id` (`seofilter_filter_id`), CONSTRAINT `FK_seofilter_filters_orders_seofilter_filters` FOREIGN KEY (`seofilter_filter_id`) REFERENCES `seofilter_filters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; CREATE TABLE IF NOT EXISTS `seofilter_filters_urls` ( `id` int(11) NOT NULL AUTO_INCREMENT, `seofilter_filter_id` int(11) NOT NULL, `seo_url` varchar(255) NOT NULL, `seo_titre` varchar(255) NOT NULL, `seo_description` varchar(255) NOT NULL, `description` text, `created` datetime NOT NULL, `modified` datetime NOT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `seofilter_filter_id_seo_url` (`seofilter_filter_id`,`seo_url`) USING BTREE, CONSTRAINT `FK_seofilter_filters_urls_seofilter_filters` FOREIGN KEY (`seofilter_filter_id`) REFERENCES `seofilter_filters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
更新文件 config/app.php
[ // ... 'SeoFilter' => [ 'config' => [ 'paginate' => [ 'enabled' => true, 'items_per_page' => 10 ], 'countResults' => true, // Si activé, renvoie le nombre de résultats après application du filtre 'previewResults' => false // Si activé, affiche le nombre de résultats après application d'un critère après ceux-ci ] ] ]
创建过滤器
首先,需要创建一个插件能够工作的过滤器。访问表 seofilter_filters
并创建您的第一个过滤器。例如
INSERT INTO `seofilter_filters` (`name`, `slug`, `controller`, `action`, `model`, `function_find`, `element`, `titre`, `seo_titre`, `seo_description`, `is_active`, `created`, `modified`) VALUES ('Produits', 'categories', 'Categories', 'details', 'Produits', 'findItemsInParentCategory', 'carte_produit', 'Les produits', 'lorem', 'lorem', 1, NOW(), NOW());
这一行指示插件,在 /categories url 上可以有一个后续的过滤器。列 model 和列 function_find 指示用于获取过滤器数据的调用方法。
// src/Model/Table/ProduitsTable.php public function findItemsInParentCategory(array $conditions = [], array $order = []): Query{ // Récupération des données... // Penser à intégrer les paramètres $conditions et $order à votre requête. }
在控制器中
// src/Controller/CategoriesController.php public function details(){ $this->loadComponent('SeoFilter.SeoFilter'); // Récupérer les conditions passées dans l'URL $conditionsFilter = $this->SeoFilter->getConditions(); // Récupération des données avec la méthode définie $results = $this->fetchTable('Produits')->findItemsInParentCategory($conditionsFilter); $this->set('items', $results->all()); }
在视图中,可以通过插入数据库中的相同元素来显示结果。
// Dans une vue <?php foreach ($items as $i => $item): ?> <?= $this->element('carte_produit', ['item' => $item]) ?> <?php endforeach; ?>
创建过滤条件
为了能够过滤我们的过滤器上的元素,需要向它提供条件。首先执行以下查询
INSERT INTO `seofilter_filters_criteres` (`seofilter_filter_id`, `name`, `slug`, `model`, `colonne`, `colonne_label`, `function_find_values`, `ordre`, `is_active`, `created`, `modified`) VALUES (1, 'Catégorie', 'categorie', 'Categories', 'slug', 'titre', 'findValuesForFilter', 1, 1, NOW(), NOW());
这一行指示为创建的过滤器添加一个 类别 条件。为了按此条件排序,需要传递一个 categorie- slug,后跟所需的参数。后续的参数将在 Categories 模型的 slug 字段中获取。(这些数据通过在控制器中调用 SeoFilter::getConditions() 返回的 URL 获取)
为了在视图中动态创建这些过滤器,可以在 function_find_values 列中传递模型的方法,在我们的例子中
// src/Model/Table/CategoriesTable.php public function findValuesForFilter(): Query{ return $this->find()->where(['Categories.is_active' => true])->order(['Categories.ordre' => 'ASC']); }
// src/Controller/CategoriesController.php public function details(){ // ... // Construction des filtres $this->SeoFilter->getFilterData(); }
在视图中
foreach ($seo_filter->seofilter_filters_criteres as $seofilter_filters_criteres) { echo $seofilter_filters_criteres->name // Nom du critère $slug = $seofilter_filters_criteres->slug; if (isset($values_for_seofilter_filters_criteres[$seofilter_filters_criteres->id])) { $filtre_criteres = $values_for_seofilter_filters_criteres[$seofilter_filters_criteres->id]; foreach ($filtre_criteres as $filtre_critere) { $value_input = $filtre_critere->{$seofilter_filters_criteres->colonne}; $label_input = $filtre_critere->{$seofilter_filters_criteres->colonne_label}; $checked = false; foreach ($seo_filter_criteres_values as $value) { if ($value['slug'] == $slug) { if (!is_array($value['value'])) { $value['value'] = [$value['value']]; } foreach ($value['value'] as $value_selected) { if ($value_selected == $value_input) { $checked = true; break; } } } } ?> <input <?= ($checked ? 'checked="checked"' : '') ?> class="" name="seofilter_filters_criteres[<?= $slug ?>][]" value="<?= $value_input ?>" type="checkbox" id="seofilter_filters_criteres-<?= $slug ?>-<?= $value_input ?>"> <label for="seofilter_filters_criteres-<?= $slug ?>-<?= $value_input ?>"><?= $label_input ?></label> } } }
Ajax 重新加载
为了简化 Ajax 处理,建议将所有条件和排序放入一个表单中
$(function() { $('#filtres input, #filtres select').on('change', function() { var data_filter = $('#filtres').serializeArray(); $.post( '<?= $this->Url->build('/seo-filter/render/' . $seo_filter->slug) ?>', data_filter, function(data) { window.history.pushState("", "", data.url); $('#js-products-container').html(data.html); } ); }); });
待办事项列表
- 与 CakePHP 的
Paginator
组件关联的分页系统 - 是否在应用过滤器后显示结果数量的括号
- 向渲染元素传递多个参数的选项