- 后台联动菜单 + 前台下拉列表调用:这是最标准、最灵活的方式,适合在发布文章、产品等地方选择地区,或者在前台表单中使用。
- 直接调用
area表数据:这种方式更直接,适合制作一个静态的地区列表,比如网站底部的“地区导航”。
下面我将详细讲解这两种方法。

(图片来源网络,侵删)
后台联动菜单 + 前台下拉列表调用(推荐)
这种方式利用了织梦的“联动类型”功能,将后台的省市区数据与前台的下拉菜单完美结合。
第一步:在后台创建联动菜单
-
登录织梦后台,进入
核心->网站栏目管理->联动类别管理。 -
添加顶级类别:
- 点击
增加顶级类别。 - 类别名称:填写
省份。 - 类别目录:可以留空或填写
province。 - 是否开启:选择
是。 - 内容模型:选择
普通文章或其他你需要的模型。 - 是否支持子类:选择
是。 - 点击“确定”。
- 点击
-
为“省份”添加子类别(市):
(图片来源网络,侵删)- 在刚创建的“省份”类别后面,点击
增加子类。 - 类别名称:填写
城市。 - 类别目录:可以留空或填写
city。 - 是否开启:选择
是。 - 内容模型:选择
普通文章。 - 是否支持子类:选择
是。 - 点击“确定”。
- 在刚创建的“省份”类别后面,点击
-
为“城市”添加子类别(区/县):
- 在刚创建的“城市”类别后面,点击
增加子类。 - 类别名称:填写
区县。 - 类别目录:可以留空或填写
area。 - 是否开启:选择
是。 - 内容模型:选择
普通文章。 - 是否支持子类:选择
否(区县通常是最底层)。 - 点击“确定”。
- 在刚创建的“城市”类别后面,点击
-
导入数据:
- 现在你有了一个“省份 -> 城市 -> 区县”的三级联动菜单结构。
- 你需要将
dede_area表的数据导入到这个联动菜单中,织梦官方提供了数据导入工具。 - 进入
系统->SQL命令行工具。 - 在“运行SQL文件”选项卡下,点击“浏览”,选择织梦安装目录下的
/data/area/文件夹中的sql文件(sql文件夹里有sql文件)。 - 点击“上传运行”。
- 注意:这个过程可能会因为服务器环境不同而失败,如果失败,你可能需要手动编写
INSERT语句来填充dede_arctype表,但这非常繁琐,更简单的方法是使用一些现成的“联动菜单数据导入”插件,在织梦官方论坛或第三方市场可以找到。
第二步:在模板中调用联动菜单
联动菜单已经创建并填充了数据,你可以在任何模板文件(如 article_add.htm 发布文章页,或者自定义的前台模板)中调用它。
织梦提供了专门的标签 {dede:sonchannel} 和 {dede:channel} 来实现联动效果,但更常用和方便的是使用 option 标签配合 getareas 函数。
示例代码:一个完整的省市区三级联动选择框
<form action="" method="post">
<div>
<label for="province">省份:</label>
<select name="province" id="province" onchange="showCity(this.value)">
<option value="0">请选择省份</option>
{dede:global name='cfg_getareas' function='GetAreaList(@me, 0)'/}
</select>
</div>
<div>
<label for="city">城市:</label>
<select name="city" id="city" onchange="showArea(this.value)">
<option value="0">请选择城市</option>
</select>
</div>
<div>
<label for="district">区县:</label>
<select name="district" id="district">
<option value="0">请选择区县</option>
</select>
</div>
</form>
<script language="javascript" type="text/javascript">
// 获取城市列表
function showProvince(pid) {
// 此函数通常在页面加载时调用,以初始化省份列表
// 上面的 {dede:global} 标签已经完成了这个工作
}
// 获取城市列表
function showCity(pid) {
var cityObj = document.getElementById("city");
cityObj.options.length = 1; // 清空城市列表,保留第一个“请选择”
if (pid == 0) return;
// 使用 AJAX 调用 getAreas.php 文件
var myajax = new DedeAjax(taget_obj, false, true, '', '', 0);
myajax.SendGet2("/plus/getAreas.php?upid=" + pid);
DedeAjax = null;
}
// 获取区县列表
function showArea(cid) {
var areaObj = document.getElementById("district");
areaObj.options.length = 1; // 清空区县列表,保留第一个“请选择”
if (cid == 0) return;
var myajax = new DedeAjax(taget_obj, false, true, '', '', 0);
myajax.SendGet2("/plus/getAreas.php?upid=" + cid);
DedeAjax = null;
}
</script>
代码解释:
-
省份下拉框:
{dede:global name='cfg_getareas' function='GetAreaList(@me, 0)'/}这是关键,它会调用GetAreaList函数,从dede_area表中读取topid为 0 的所有记录(即所有省份),并生成<option>
-
城市和区县下拉框:
- 初始时,它们只有一个“请选择”的选项。
- 当用户选择一个省份后,
onchange="showCity(this.value)"事件被触发。 showCity(pid)函数使用 AJAX 向/plus/getAreas.php发送请求,参数是所选省份的id。getAreas.php是织梦自带的一个文件,它会根据接收到的upid参数,查询dede_area表,返回对应的城市列表,并以 JavaScript 的形式动态更新到id为city的<select>中。- 城市选择后,
showArea(cid)函数同理,会动态加载出对应的区县列表。
直接调用 area 表数据(静态列表)
如果你不需要三级联动的交互效果,只想在页面上展示一个静态的地区列表(比如网站地图),可以直接查询数据库。
使用 {dede:sql}
{dede:sql} 标签允许你直接执行SQL语句并输出结果。
示例1:列出所有省份
<h3>省份列表</h3>
<ul>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 0 ORDER BY `id` ASC'}
<li><a href="[field:name function='MakeOneAddUrl(@me)'/]">[field:name/]</a></li>
{/dede:sql}
</ul>
示例2:列出某个省份下的所有城市(例如ID为1的省份)
<h3>广东省下的城市</h3>
<ul>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 1 ORDER BY `id` ASC'}
<li><a href="[field:name function='MakeOneAddUrl(@me)'/]">[field:name/]</a></li>
{/dede:sql}
</ul>
示例3:制作一个递归的地区列表(显示所有省市区)
这个稍微复杂一点,需要自定义一个函数来实现递归,这里提供一个简化的非递归版本,展示两级结构。
<h3>所有省份及主要城市</h3>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 0 ORDER BY `id` ASC'}
<div class="province">
<h4>[field:name/]</h4>
<ul class="cities">
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = [field:id/] LIMIT 0, 5'}
<li>[field:name/]</li>
{/dede:sql}
</ul>
</div>
{/dede:sql}
注意:内层的 {dede:sql} 会根据外层的 id 动态执行,实现嵌套查询。
总结与建议
方法
优点
缺点
适用场景
方法一(联动菜单)
标准、灵活、与后台数据同步、支持动态交互(AJAX)。
设置相对复杂,需要导入数据,依赖JS和织梦的 getAreas.php。
时选择地区、前台搜索筛选、用户注册等需要交互的场景。
方法二(直接调用)
简单直接、性能好(无JS)、适合静态展示。
数据是静态的,无法联动,需要手动指定 topid。
网站页脚的“地区导航”、网站地图、静态的地区展示列表。
对于绝大多数情况,强烈推荐使用方法一,因为它更符合织梦的设计理念,且功能更强大,只有在制作纯静态展示时,才考虑方法二。
{dede:sql} 标签允许你直接执行SQL语句并输出结果。
示例1:列出所有省份
<h3>省份列表</h3>
<ul>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 0 ORDER BY `id` ASC'}
<li><a href="[field:name function='MakeOneAddUrl(@me)'/]">[field:name/]</a></li>
{/dede:sql}
</ul>
示例2:列出某个省份下的所有城市(例如ID为1的省份)
<h3>广东省下的城市</h3>
<ul>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 1 ORDER BY `id` ASC'}
<li><a href="[field:name function='MakeOneAddUrl(@me)'/]">[field:name/]</a></li>
{/dede:sql}
</ul>
示例3:制作一个递归的地区列表(显示所有省市区)
这个稍微复杂一点,需要自定义一个函数来实现递归,这里提供一个简化的非递归版本,展示两级结构。
<h3>所有省份及主要城市</h3>
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = 0 ORDER BY `id` ASC'}
<div class="province">
<h4>[field:name/]</h4>
<ul class="cities">
{dede:sql sql='SELECT id, name FROM `dede_area` WHERE `topid` = [field:id/] LIMIT 0, 5'}
<li>[field:name/]</li>
{/dede:sql}
</ul>
</div>
{/dede:sql}
注意:内层的 {dede:sql} 会根据外层的 id 动态执行,实现嵌套查询。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 方法一(联动菜单) | 标准、灵活、与后台数据同步、支持动态交互(AJAX)。 | 设置相对复杂,需要导入数据,依赖JS和织梦的 getAreas.php。 |
时选择地区、前台搜索筛选、用户注册等需要交互的场景。 |
| 方法二(直接调用) | 简单直接、性能好(无JS)、适合静态展示。 | 数据是静态的,无法联动,需要手动指定 topid。 |
网站页脚的“地区导航”、网站地图、静态的地区展示列表。 |
对于绝大多数情况,强烈推荐使用方法一,因为它更符合织梦的设计理念,且功能更强大,只有在制作纯静态展示时,才考虑方法二。
