场景分析
“筛选文章”是一个很宽泛的概念,具体需求可能包括:
- 按栏目筛选:只显示某个特定栏目下的文章。
- 按自定义字段筛选:根据文章的某个附加属性(如:产品型号、价格区间、发布年份、标签等)进行筛选。
- 按关键字筛选或内容中搜索特定关键字。
下面我将针对这几种常见场景,提供具体的解决方案。
使用织梦自带标签进行简单筛选(按栏目、关键字)
这是最基础的方法,适用于不需要复杂自定义字段的场景。
按栏目筛选
织梦的 arclist 标签本身就支持 typeid 参数来指定栏目ID。
标签语法:
{dede:arclist typeid='栏目ID' titlelen='30' row='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
</li>
{/dede:arclist}
参数说明:
typeid='栏目ID':这是关键,你可以填写一个或多个栏目ID,用逗号隔开,typeid='1,2',如果想排除某个栏目,可以使用notypeid,len='30'`:标题长度,字符数。row='10':获取的文章数量。[field:arcurl/]:文章链接。[field:title/]。[field:pubdate/]:发布日期,这里用function进行了格式化。
按关键字筛选
织梦的 search 标签专门用于搜索。
标签语法:
{dede:search}
<form action="{dede:global.cfg_cmspath/}/plus/search.php" name="formsearch">
<input type="hidden" name="kwtype" value="0" />
<input type="text" name="q" class="search-keyword" placeholder="请输入关键字" />
<button type="submit" class="search-submit">搜索</button>
</form>
{/dede:search}
<!-- 搜索结果列表 -->
{dede:global name='keyword'/} 的搜索结果:
{dede:list pagesize='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<p>[field:info/]...</p>
</li>
{/dede:list}
这个方法通常用于一个专门的搜索页面,而不是在首页或其他页面动态筛选。
使用自定义表单 + SQL查询(核心方法,最灵活)
这是实现复杂筛选(如按自定义字段筛选)的标准方法,步骤如下:
步骤 1:在文章模型中添加自定义字段
假设我们要做一个“产品展示”筛选,需要按“产品类型”和“适用品牌”来筛选。
- 登录织梦后台,进入 [核心] -> [内容模型管理]。
- 找到你文章所在的内容模型(通常是“文章”),点击后面的 [字段管理]。
- 点击 [添加新字段]。
- 字段名称:填
product_type(英文,不含空格)。 - 字段提示:填“产品类型”(这是后台显示的名称)。
- 字段类型:选择“单行文本”或“下拉列表”,如果选择下拉列表,需要在“选项值”中填写,如:
手机,电脑,平板,每行一个。 - 是否为前台投稿使用:根据需要选择。
- 是否显示在列表页:务必选择“是”,这样才能在后台文章列表中看到和编辑。
- 字段名称:填
- 用同样的方法再添加一个字段,
brand(字段提示:“适用品牌”)。
步骤 2:编写筛选表单(前端)
在你的页面模板(如 index.htm)中,添加一个筛选表单。
<form name="searchform" action="/plus/list.php" method="get">
<!-- 隐藏字段,指定栏目ID,这里假设是产品栏目ID=5 -->
<input type="hidden" name="typeid" value="5" />
<!-- 产品类型筛选 -->
<select name="product_type">
<option value="">全部类型</option>
<option value="手机">手机</option>
<option value="电脑">电脑</option>
<option value="平板">平板</option>
</select>
<!-- 适用品牌筛选 -->
<input type="text" name="brand" placeholder="输入品牌关键词" />
<button type="submit">筛选</button>
</form>
关键点:
form的action指向织梦的列表页plus/list.php。input和select的name属性必须和你 步骤1 中定义的字段名(product_type,brand)完全一致。typeid用于限定只在某个栏目下搜索,这是很好的实践。
步骤 3:编写PHP代码进行SQL查询(后端)
这是最关键的一步,你需要一个PHP文件来接收筛选参数,并执行查询。
- 在你的网站根目录下创建一个新文件,
search_products.php。 - 将以下代码复制到该文件中,并根据你的实际情况进行修改。
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once DEDEINC."/arc.partview.class.php";
// 1. 接收筛选参数
$typeid = isset($_GET['typeid']) ? intval($_GET['typeid']) : 0;
$product_type = isset($_GET['product_type']) ? trim($_GET['product_type']) : '';
$brand = isset($_GET['brand']) ? trim($_GET['brand']) : '';
// 2. 构建SQL查询的WHERE条件
$where = " WHERE arc.arcrank > -1 "; // 只显示已审核的文章
if ($typeid > 0) {
$where .= " AND arc.typeid = $typeid ";
}
if (!empty($product_type)) {
// 注意:这里使用了[field:product_type/]的存储方式,即字段值直接存在附加表里
// 我们需要关联附加表 `dede_addonarticle` (如果你的文章模型ID是1)
// 如果字段在别的附加表,请修改表名
$where .= " AND arc.id IN (SELECT aid FROM dede_addonarticle WHERE product_type = '" . $dsql->EscapeString($product_type) . "') ";
}
if (!empty($brand)) {
$where .= " AND arc.id IN (SELECT aid FROM dede_addonarticle WHERE brand LIKE '%" . $dsql->EscapeString($brand) . "%') ";
}
// 3. 执行查询并获取数据
$sql = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,
tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath
FROM `dede_archives` arc
LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id
$where
ORDER BY arc.sortrank DESC";
$dsql->SetQuery($sql);
$dsql->Execute();
// 4. 循环输出结果
echo "<ul>";
while ($row = $dsql->GetArray()) {
// 处理标题、链接等
$title = $row['title'];
$arcurl = GetOneArchive($row['id']);
$pubdate = MyDate('Y-m-d', $row['pubdate']);
// 获取附加表里的自定义字段值
$addRow = $dsql->GetOne("SELECT product_type, brand FROM dede_addonarticle WHERE aid = '{$row['id']}'");
$p_type = isset($addRow['product_type']) ? $addRow['product_type'] : '';
$p_brand = isset($addRow['brand']) ? $addRow['brand'] : '';
echo "<li>";
echo "<a href='{$arcurl['arcurl']}'>{$title}</a>";
echo "<p>类型: {$p_type} | 品牌: {$p_brand}</p>";
echo "<span>发布日期: {$pubdate}</span>";
echo "</li>";
}
echo "</ul>";
?>
步骤 4:关联模板
为了让你的 search_products.php 文件显示美观,你需要创建一个对应的模板文件。
- 在你的模板目录(如
/templets/default/)下创建一个文件,命名为search_products.htm。 - 在这个模板文件里,你可以使用HTML和织梦标签来设计列表的样式。
- 最重要的一步:在
search_products.php文件的最后,加上以下代码来调用模板:
// ... 在PHP代码的末尾 ... // 调用模板 $tpl = new PartView(); $tpl->SetTemplet($cfg_basedir . $cfg_templets_dir . "/search_products.htm"); $tpl->Display(); ?>
当你访问 search_products.php 并填写筛选条件时,它就会执行查询,并将结果按照 search_products.htm 的样式显示出来。
使用AJAX实现无刷新筛选(提升用户体验)
方法二每次筛选都会刷新整个页面,体验不好,我们可以结合jQuery和AJAX来实现无刷新筛选。
核心思路:
- 前端筛选表单的
submit事件被阻止,改为用$.ajax发送数据。 - 后端 PHP 文件(如
search_products.php)需要能判断是否是AJAX请求,并只返回JSON格式的数据,而不是完整的HTML页面。 - 前端JS接收到JSON数据后,用JavaScript动态更新页面上的列表内容。
后端PHP (search_products_ajax.php) 修改
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
// 只接收AJAX请求
if (!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
exit('仅支持AJAX请求');
}
// ... (接收参数和构建SQL的代码与方法二完全相同) ...
$dsql->SetQuery($sql);
$dsql->Execute();
$data = [];
while ($row = $dsql->GetArray()) {
$arcurl = GetOneArchive($row['id']);
$addRow = $dsql->GetOne("SELECT product_type, brand FROM dede_addonarticle WHERE aid = '{$row['id']}'");
$data[] = [
'title' => $row['title'],
'arcurl' => $arcurl['arcurl'],
'pubdate' => MyDate('Y-m-d', $row['pubdate']),
'product_type' => isset($addRow['product_type']) ? $addRow['product_type'] : '',
'brand' => isset($addRow['brand']) ? $addRow['brand'] : '',
];
}
// 返回JSON数据
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
?>
前端模板和JS
<!-- 筛选表单 (同方法二) -->
<form id="filter-form">
<input type="hidden" name="typeid" value="5" />
<select name="product_type">
<option value="">全部类型</option>
<option value="手机">手机</option>
<option value="电脑">电脑</option>
<option value="平板">平板</option>
</select>
<input type="text" name="brand" placeholder="输入品牌关键词" />
<button type="submit">筛选</button>
</form>
<!-- 结果列表容器 -->
<div id="search-results">
<!-- 初始可以显示一些默认内容,或者为空 -->
<p>请使用上方表单进行筛选。</p>
</div>
<!-- 引入jQuery库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
// 监听筛选表单的提交事件
$('#filter-form').on('submit', function(e) {
// 1. 阻止表单默认提交行为
e.preventDefault();
// 2. 获取表单数据
var formData = $(this).serialize();
// 3. 发送AJAX请求
$.ajax({
url: '/search_products_ajax.php', // 你的AJAX处理文件
type: 'GET',
data: formData,
dataType: 'json',
success: function(response) {
// 4. 成功后,清空结果容器
var html = '';
if (response.length > 0) {
// 5. 遍历返回的数据,生成HTML
$.each(response, function(index, item) {
html += '<li>';
html += '<a href="' + item.arcurl + '">' + item.title + '</a>';
html += '<p>类型: ' + item.product_type + ' | 品牌: ' + item.brand + '</p>';
html += '<span>发布日期: ' + item.pubdate + '</span>';
html += '</li>';
});
} else {
html = '<p>没有找到符合条件的文章。</p>';
}
// 6. 将生成的HTML更新到页面上
$('#search-results').html('<ul>' + html + '</ul>');
},
error: function(xhr, status, error) {
console.error('请求失败:', error);
$('#search-results').html('<p>筛选出错,请稍后再试。</p>');
}
});
});
});
</script>
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 自带标签 | 简单、无需编程,织梦原生支持 | 灵活性差,无法满足复杂筛选需求 | 按栏目、关键字等简单筛选 |
| PHP+SQL | 非常灵活,可满足任何筛选需求,功能强大 | 需要编写PHP代码,对新手有一定门槛 | 绝大多数复杂筛选需求,如按自定义字段筛选 |
| AJAX+PHP | 用户体验好,页面无刷新,响应迅速 | 实现最复杂,需要JS和PHP配合 | 对用户体验要求高的筛选功能,如电商筛选、产品筛选 |
对于你的需求“单独调取织梦帅选文章”,方法二 是最核心、最应该掌握的技能,如果你希望你的网站更现代化,方法三 是最佳选择。
