如何使用 Backbone.js 增强多语言网站导航?

Posted

技术标签:

【中文标题】如何使用 Backbone.js 增强多语言网站导航?【英文标题】:How to use Backbone.js to enhance a multi-language website navigation? 【发布时间】:2013-01-23 17:05:31 【问题描述】:

我有一个多语言网站,显示几个(十几个)内容页面,漂亮的网址如下:

example.com              <- home for default language (french)
example.com/biographie   <- page 1
example.com/en           <- home for english language
example.com/en/biography <- page 1 english translation

我想将页面合并在一起并提供完整的 ajax 导航,就像 Pitchfork 所做的那样。最重要的是保留非 javascript 客户端(SEO、社交网络和其他)的页面视图。

服务器提供完整的网页,然后在 Backbone 初始化时,它会预取其他页面并将其注入 DOM 以加快导航速度。当我导航到另一个页面时,我使用 Backbone 内置的 History API 在历史记录中记录新 URL,并更改视图以显示请求的页面。

var Navigator = Backbone.Router.extend(

  routes: 
    "*page":                "showPage",
  ,

  showPage: function(page) 
    this.pages[page].show();
  


我的问题是管理 i18n(我的意思是翻译的页面)。如何设置我的路由器来处理语言?我应该如何处理语言切换?

routes: 
  "*page":                "showPageFr",
  "en/*page":             "showPageEn",
,

showPageFr: function(page)
  showPage(page, 'fr');
,

showPageEn: function(page)
  showPage(page, 'en');
,

showPage: function(page, lang) 
  // How should I manage 'lang' parameter here ?
  this.pages[page].show();

我查看了 i18n JS 框架,但我认为我不需要它,因为我想翻译整个页面内容,而不是一些 UI 元素。所有翻译部分都在服务器端进行管理。

【问题讨论】:

***.com/questions/11865503/… @Antonimo :我不明白为什么这个问题与我的有关。我没有包含所有内容翻译的 JSON 文件,但我宁愿将翻译后的页面视为不同的页面(具有不同的 URL 和不同的 ID) 对,您想将语言 (/fr/) 作为属性传递给服务器,***.com/questions/7445353/…,可能会有所帮助 @Antonimo :不,我的问题不在服务器端。我使用 Wordpress 并有重写规则,按照我需要的方式管理语言。我的问题在客户端。事实上,当我调用Backbone.history.start 时,我想我必须定义一个不同的词根:“/”表示法语,“/en/”表示英语。您认为这可能是一个好的解决方案吗? 是的,我现在也需要一个解决方案,发现这是解决问题的方法。 【参考方案1】:

首先,这是您可以设置路由器以保持其清洁的方法,希望如此。

您拥有将提取法语内容的BaseRouter,如果您想添加其他语言,则必须使用不同的语言代码覆盖BaseRouter。 (见EnglishRouter

// This is the base Router
var BaseRouter = Backbone.Router.extend(
    language: null,
    routes: 
        '*page': 'showPage'
    ,

    _bindRoutes: function() 
        // this._bindRoutes() is called in Backbone.Router before
        // initialize(). Overriding native _bindRoutes method to
        // accomodate the custom logic in changing route.
        var me = this;

        if (this.language) 
            console.log('Updating routes for ' + this.language);

            _.each(_.keys(this.routes), function(key) 
                me.routes[me.language + '/' + key] = me.routes[key];
                delete me.routes[key];
            );
        

        // Call native _bindRoutes method.
        Backbone.Router.prototype._bindRoutes.apply(this, arguments);
    ,

    getLanguage: function() 
        return this.language || 'fr';
    ,

    showPage: function(page) 
        console.log('Showing ' + page + ' in ' + this.getLanguage());
    
);

var EnglishRouter = BaseRouter.extend(
    language: 'en'
);

这是与之配套的小提琴:http://jsfiddle.net/dashk/yTS33/

在为不同页面制定内容策略方面 - 根据您所描述的内容(所有内容而不是正常的特定字符串),可以选择单个字典。 (不过我认为这并不优雅。)但是,当您向网站添加更多语言时,您可能需要考虑根据需要动态加载语言,而不是仅仅将所有语言放在一个文件中。

这是字典的一个示例:

var PageContent = 
    'fr': 
        'happyPage': 'Happy Page Content in French',
        'fridayPage': 'Friday page Content in French'
    ,
    'en': 
        'happyPage': 'Happy Page Content in English',
        'fridayPage': 'Friday page Content in English'
    
;

【讨论】:

感谢您的回答 DashK:+1。这是一个很好的方向,所以我会尝试一下,并将你的答案标记为好的答案,当我能够让它发挥作用时。 关于内容本身,我不会使用字典,而是使用标记本身。我的内容充满了 html 标记(带有视频和图像标签)。我根据请求通过 ajax 加载它并将其插入到 DOM 的正确位置。 我在您的回答中看到了两个问题。首先:在您提供的 Fiddle 中,当我单击 Happy Page Content in French 链接时,我会看到“法语的快乐页面内容”,反之亦然。我不明白为什么,但逻辑是颠倒的。第二:我在自己的代码中尝试过,似乎initialize 调用来不及更改路由。旧路线仍然匹配,新路线在更改后不匹配。 抱歉,我的意思是“在您提供的 Fiddle 中,当我点击 Happy Page English 链接时,我会看到“法语的快乐页面内容”,反之亦然。” @FabienQuatravaux - 我的错误。我忽略了 Backbone.Router._bindRoutes 实际上是在 .initialize() 之前调用的。我已经更新了 Fiddle 和更正此问题的答案。【参考方案2】:

感谢 DashK 让我走上了好路。 解决方案是在检测到英语时更改历史根。

var Router = Backbone.Router.extend(
    language: null,

    initialize: function(options)

        this.language = options.language;
        Backbone.history.start(pushState: true, root:'/'+ (this.language ? this.language : ''));
    ,

    routes: 
        ":chapter(/*subpage)": "go",
        "" : "go" // match home route
    ,

    go: function(chapter, subpage) 

    
);

// wait for the document to be ready
$(function()
    var lang;
    if($.url().segment(1) === 'en')  lang = 'en'; 

    new Router(language: lang);
);

那么,当我在代码中使用router.navigate("some-chapter") 时,我不必关心语言。

【讨论】:

这种方法有它自己的缺点。网站上的所有链接也应该没有市场,因此如果我们在另一个选项卡上打开它们,我们会得到全球市场页面,而不是其本地化版本。我说的是单页应用程序,站点内的所有链接都通过主干路由器提供服务。

以上是关于如何使用 Backbone.js 增强多语言网站导航?的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何创建一个多语言网站

Codeigniter:如何使用数据库和用户会话数据构建多语言网站?

做一个友好的多语言网站

如何在多语言 asp.net MVC 网站的 URL 中支持有语言和无语言的路由

SEO优化多域和多语言网站[关闭]

纸壳CMS可视化建站系统搭建多语言网站