织梦CMS如何实现中英文双语?

99ANYc3cd6
预计阅读时长 30 分钟
位置: 首页 织梦建站 正文

核心思路

无论采用哪种方法,实现双语网站的核心思路都是一致的:

  1. 语言切换:提供一种方式让用户在中文和英文之间切换,通常是通过URL中的参数来标识当前语言,
    • 中文:http://www.yoursite.com/
    • 英文:http://www.yoursite.com/en/http://www.yoursite.com/?lang=en
  2. 内容关联:建立一个机制,将中文内容和英文内容关联起来,这样,当用户切换语言时,系统能找到对应的内容。
  3. 模板适配:根据当前语言状态,在模板中调用对应语言的内容。

使用栏目别名(最常用,推荐)

这是最主流、最符合织梦CMS设计思想的方法,尤其适合内容结构不经常变更的网站。

实现原理

为同一个栏目创建两个版本:一个中文栏目,一个英文栏目,然后通过栏目的 typeiden typeid(或其他自定义字段)来建立关联,通过URL中的路径(如 /en/)来判断当前语言,并动态加载对应的栏目ID。

详细步骤

栏目结构设计

  • 在后台“栏目管理”中,创建所有需要的栏目。
  • 示例
    • 创建一个顶级栏目“首页” (Home),ID假设为 1
    • 创建一个顶级栏目“关于我们” (About Us),ID假设为 2
    • 再创建一个英文版的顶级栏目“About Us”,ID假设为 3

设置栏目别名

  • 在“栏目管理”中,编辑每个中文栏目。
  • 在“栏目别名”或“高级选项”中,填写其对应的英文栏目ID,在“关于我们”栏目(ID=2)的自定义字段中添加一个字段 en_typeid,并填入 3
  • 同样,在英文栏目(ID=3)中添加一个 zh_typeid 字段,并填入 2

创建语言切换链接 在网站头部模板(如 head.htm)中,放置语言切换按钮。

<div class="language-switcher">
    <a href="{dede:global.cfg_basehost/}/">中文</a>
    <a href="{dede:global.cfg_basehost/}/en/">English</a>
</div>

这里我们用URL路径 /en/ 来代表英文。

修改模板,实现动态内容调用 这是最关键的一步,我们需要在模板中判断当前语言,并调用对应栏目的内容。

  • 首页模板 (index.htm): 首页通常是一个聚合页,需要根据语言调用不同栏目的文章列表。

    {dede:php}
    // 判断当前语言
    $lang = 'zh'; // 默认为中文
    if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
        $lang = 'en';
    }
    // 获取当前栏目的ID,首页通常是1
    $typeid = $lang == 'en' ? 3 : 1; // 英文对应栏目ID为3,中文为1
    // 将typeid变量传递给dede标签
    $GLOBALS['typeid'] = $typeid;
    {/dede:php}
    <h1>{dede:field.title/}</h1>
    <!-- 调用当前语言栏目的文章列表 -->
    {dede:arclist row="10" titlelen="30"}
    <li><a href="[field:arcurl/]">[field:title/]</a></li>
    {/dede:arclist}
  • 列表页模板 (list_xxx.htm): 列表页需要根据当前栏目,动态获取其关联的英文或中文栏目ID。

    {dede:php}
    // 判断当前语言
    $lang = 'zh';
    if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
        $lang = 'en';
    }
    // 获取当前栏目的ID
    $current_typeid = $GLOBALS['typeid'];
    // 获取关联的栏目ID
    if ($lang == 'en') {
        // 如果是英文,则查询当前栏目的 zh_typeid 字段
        $en_typeid = $dsql->GetOne("SELECT zh_typeid FROM `#@__arctype` WHERE id = $current_typeid");
        $typeid = $en_typeid['zh_typeid'];
    } else {
        // 如果是中文,则查询当前栏目的 en_typeid 字段
        $zh_typeid = $dsql->GetOne("SELECT en_typeid FROM `#@__arctype` WHERE id = $current_typeid");
        $typeid = $zh_typeid['en_typeid'];
    }
    // 将typeid变量传递给dede标签
    $GLOBALS['typeid'] = $typeid;
    {/dede:php}
    <h1>{dede:field.title/}</h1>
    <!-- 调用关联栏目的文章列表 -->
    {dede:arclist row="10" titlelen="30"}
    <li><a href="[field:arcurl/]">[field:title/]</a></li>
    {/dede:arclist}
  • 页 (article_article.htm):页的逻辑与列表页类似,也需要通过PHP代码找到当前文章对应语言的版本。

    {dede:php}
    // 判断当前语言
    $lang = 'zh';
    if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
        $lang = 'en';
    }
    // 获取当前文章的栏目ID
    $current_typeid = $GLOBALS['typeid'];
    // 获取关联的栏目ID (逻辑同列表页)
    if ($lang == 'en') {
        $en_typeid = $dsql->GetOne("SELECT zh_typeid FROM `#@__arctype` WHERE id = $current_typeid");
        $typeid = $en_typeid['zh_typeid'];
    } else {
        $zh_typeid = $dsql->GetOne("SELECT en_typeid FROM `#@__arctype` WHERE id = $current_typeid");
        $typeid = $zh_typeid['en_typeid'];
    }
    // 查找同一栏目下,标题(或其他字段)相似的文章作为对应版本
    // 这是一个简化的查找逻辑,实际中可能需要更复杂的关联,比如在文章表里加一个关联字段
    $arcid = $GLOBALS['arcid'];
    $query = "SELECT id FROM `#@__archives` WHERE typeid = $typeid AND title LIKE '%".GetOneArc($arcid)['title']."%'";
    $row = $dsql->GetOne($query);
    $related_arcid = $row['id'];
    // 生成对应语言的文章链接
    if ($related_arcid) {
        $GLOBALS['related_url'] = GetOneArchive($related_arcid)['arcurl'];
    }
    {/dede:php}
    <h1>{dede:field.title/}</h1>
    <div class="content">
        {dede:field.body/}
    </div>
    <!-- 添加一个“阅读英文版”或“阅读中文版”的链接 -->
    {if $related_url}
    <a href="{$related_url}">Read in {if $lang=='zh'}English{else}中文{/if}</a>
    {/if}

优点

  • SEO友好:每个语言版本都有独立的URL,搜索引擎可以分别索引。
  • 结构清晰管理结构清晰,符合织梦CMS原生逻辑。
  • 稳定可靠:不依赖第三方插件,长期使用更稳定。

缺点

  • 维护成本高需要在后台分别录入和管理,如果内容量大,会非常繁琐。
  • URL结构:需要规划好URL路径,避免混乱。

使用自定义字段(适合内容关联性强的情况)

这种方法适合栏目结构完全一致,只是语言不同的网站,它不创建额外的栏目,而是在同一个栏目下为每篇文章添加一个对应语言版本的ID。

实现原理

  1. 在文章附加表 dede_archives 中增加一个自定义字段,en_aid (English Article ID)。
  2. 发布中文文章时,同时发布或找到对应的英文文章,并将英文文章的ID填入 en_aid 字段。
  3. 在模板中,通过PHP读取当前文章的 en_aidzh_aid,从而获取关联文章的URL。

步骤

  1. 后台添加字段:在后台“核心” -> “内容模型管理” -> “普通文章” -> “字段管理”中,添加一个新字段,字段名为 en_aid,数据类型选择“数字”。

  2. 内容录入:发布一篇文章,然后发布其英文版本,在中文文章的编辑页面,找到 en_aid 字段,填入英文文章的ID,反之亦然。

  3. 模板修改

    • :通过 en_aid 字段获取关联文章ID,然后生成链接。
    {dede:php}
    $lang = 'zh';
    if (isset($_GET['lang']) && $_GET['lang'] == 'en') {
        $lang = 'en';
    }
    $en_aid = $fields['en_aid']; // 获取当前文章的英文ID
    $zh_aid = $fields['zh_aid']; // 假设你也添加了zh_aid字段
    $related_id = ($lang == 'en') ? $zh_aid : $en_aid;
    if ($related_id) {
        $archive = GetOneArchive($related_id);
        $GLOBALS['related_url'] = $archive['arcurl'];
    }
    {/dede:php}
    <h1>{dede:field.title/}</h1>
    <div class="content">
        {dede:field.body/}
    </div>
    {if $related_url}
    <a href="{$related_url}">Switch to {if $lang=='zh'}English{else}中文{/if}</a>
    {/if}

优点

  • 内容集中:同一主题的不同语言版本在后台可以放在一起管理,方便对照。
  • URL简洁:不需要创建多个栏目,URL结构可以更统一。

缺点

  • 关联复杂时需要手动关联ID,容易出错。
  • 扩展性差:如果需要增加第三种语言,需要修改数据表结构和所有模板。

使用第三方多语言插件

市面上有一些织梦CMS的多语言插件,它们封装了上述逻辑,提供了一套解决方案。

优点

  • 开箱即用:对于不想写代码的用户来说,安装插件即可使用。
  • 功能集成:通常包含语言切换、URL重写、内容同步等功能。

缺点

  • 兼容性风险:插件可能与织梦CMS的特定版本不兼容,升级CMS后可能失效。
  • 安全风险:来源不明的插件可能包含后门或漏洞。
  • 功能限制:插件的功能是固定的,难以进行深度定制。
  • 维护困难:插件作者可能停止更新,出现问题难以自行修复。

不推荐对有一定技术能力的用户依赖插件,除非是功能非常成熟且广受好评的商业插件。


最佳实践方案(推荐)

结合以上分析,我推荐 “方法一:使用栏目别名” 作为最佳实践,并对其进行优化。

  1. URL结构:采用 和 /en/ 的路径结构,这需要配置服务器伪静态规则,将所有 /en/ 开头的请求指向 index.php

    • Nginx 伪静态规则示例:
      rewrite ^/en/(.*)$ /index.php?lang=en&/$1 last;
      rewrite ^/(.*)$ /index.php?/$1 last;
    • Apache 伪静态规则示例 (.htaccess):
      <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule ^en/(.*)$ index.php?lang=en&/$1 [L]
        RewriteRule ^(.*)$ index.php?/$1 [L]
      </IfModule>
  2. 模板优化:将语言判断逻辑封装成一个公共函数或变量,避免在每个模板文件中重复编写PHP代码。

    • include/extend.func.php 文件中添加一个函数:
      // 获取当前语言对应的栏目ID
      function getLangTypeid($current_typeid, $lang = 'zh') {
          global $dsql;
          $field_name = ($lang == 'en') ? 'zh_typeid' : 'en_typeid';
          $query = "SELECT `$field_name` FROM `#@__arctype` WHERE id = $current_typeid";
          $row = $dsql->GetOne($query);
          return $row[$field_name] ? $row[$field_name] : $current_typeid; // 如果找不到,返回当前ID
      }
    • 然后在模板中直接调用这个函数,使代码更简洁。
  3. 内容管理

    • 为所有需要双语展示的栏目都创建中英文两个版本。
    • 使用自定义字段 en_typeidzh_typeid 建立强关联。
    • 后台可以创建两个不同的管理员账号,分别负责中文和英文内容的录入,以避免混乱。
  4. SEO优化

    • 在每个模板的 <head> 部分添加 hreflang 标签,告诉搜索引擎不同语言版本之间的关系。

      {dede:php}
      $current_url = $_SERVER['REQUEST_URI'];
      $zh_url = 'http://www.yoursite.com' . $current_url;
      $en_url = 'http://www.yoursite.com/en' . $current_url;
      if (strpos($current_url, '/en/') !== false) {
          // 当前是英文页面
          $zh_url = str_replace('/en/', '/', $zh_url);
          echo "<link rel=\"alternate\" hreflang=\"zh-CN\" href=\"$zh_url\" />\n";
          echo "<link rel=\"alternate\" hreflang=\"en\" href=\"$en_url\" />\n";
      } else {
          // 当前是中文页面
          $en_url = '/en' . $current_url;
          echo "<link rel=\"alternate\" hreflang=\"zh-CN\" href=\"$zh_url\" />\n";
          echo "<link rel=\"alternate\" hreflang=\"en\" href=\"$en_url\" />\n";
      }
      {/dede:php}

对于织梦CMS的中英文双语网站,“基于栏目别名的方案” 是最健壮、最灵活且SEO友好的选择,虽然初期设置和模板修改需要一些工作量,但从长远来看,它能为你提供一个稳定、可维护且对搜索引擎友好的多站架构。

-- 展开阅读全文 --
头像
织梦CMS数据库链接失败怎么办?
« 上一篇 01-21
织梦让图片栏目向左播放
下一篇 » 01-21

相关文章

取消
微信二维码
支付宝二维码

目录[+]