使用expressjs和jade的动态(i18n)链接

时间:2012-02-05 02:16:26

标签: javascript node.js internationalization express pug

我正在使用expressjs和i18n-node(https://github.com/mashpie/i18n-node)。它工作正常,除了优雅的链接。我现在拥有的是:

app.all(/^\/(\w{2}\/)+(\w*)?/, function(req, res, next) {
    var lang = req.params[0];
    var type = req.params[1];

    req.url = req.url.replace(lang, "");

    if(type !== 'javascript' && type !== 'img' && type !== 'css') {
      i18n.setLocale(lang.slice(0, 2));
    }   
    next();
});

(我希望/ foo和/ en / foo一起工作)。如果未在URL中指定语言,则会检查标题,如果不是,则默认为英语。顺便说一句,我的解决方案似乎不太理想(我必须进行手动检查以确定它是否不是静态内容),所以如果你们中的任何人有更好的解决方案,我都会听到。

现在,我真正的问题是建立内部内容的链接。如果用户在这里:“/ en / foo”,“/ bar”-link实际上应该是“/ en / bar”。我正在使用玉(除了特殊原因,这是默认的,再次接受建议..)

我尝试向Jade添加一个辅助函数:

app.helpers({
  __i: i18n.__
  ,__n: i18n.__n
  ,link_to: function(link, text) {
    //TODO: how to get request here?
    // this should be defined to the absolute base path
    var baseUrl = "/";
    // only append locale if it is part of the existing url!
    var locale = i18n.getLocale();
    return '<a href="' + baseUrl + locale + '/' + link + '">' + text + '</a>';
  }
});

..但它有很多问题:

  1. 如何获取基本网址?例如,如果网站位于“http://www.example.com/foo/bar”,并且我链接到“testLink”,则link_to将生成“http://www.example.com/foo/ bar / testLink“,而不是”/ testLink“或”http://www.example.com/testLink“等..
  2. 如何确定网址是否包含本地化参数?如果没有必要,我不想在链接中附加本地化参数。
  3. 功能本身并不好;在Jade中,它被称为:: = link_to(“testUrl”,“some link description”)。我宁愿做这样的事情: 的link_to(HREF = “someUrl”)   div一些更多的玉代码
  4. (次要)HTML直接写在JS
  5. 这样做的首选方法是什么?我一直在搜索和搜索,但无法找到一个好的答案..

    这实际上也是一个普遍的问题;即如何链接到其他内部内容,如Rails中的link_to。简单地做一个(href =“someAction”)是不够好的,因为你希望它生成绝对URL,这样漂亮的URL不会破坏静态内容链接。

    谢谢!

2 个答案:

答案 0 :(得分:2)

我使用i18n粘贴自己项目中的代码,我使用dicto类和另一个类来搜索IP语言:

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser());
  app.use(express.session({
        secret: "sessid",
        key: 'uwsid',
        store: sessionStore
  }));
  app.use(function (req,res,next) {

      if (req.session.uid) {
          req.lang = req.session.uid.lang;
          next();
      } else if (req.cookies.lang) {
          req.lang = req.cookies.lang;
          next();
      } else {

          var alang = typeof req.headers['accept-language'] != "undefined" ? req.headers['accept-language'].substr(0,2) : null;

          var ipinfows = ipinfo.getInstance();

          ipinfows.getInfo(req.connection.remoteAddress, function (err,data) {

              if (err) {
                  req.lang = alang;
                  res.cookie('lang', alang);
              } else if (data && data.error) {
                  req.lang = alang;
                  res.cookie('lang', alang);
              } else {

                  console.log("seteando");

                  req.lang = data.lang.toLowerCase();

                  for (i in countryLangs) {
                      if (countryLangs[i].indexOf(data.lang) != -1) {
                          req.lang = i;
                      }
                  }

                  if (alang != req.lang) {
                      req.langdifference = alang;
                  }

                  res.cookie('lang', req.lang);

              }

              next();

          });
      }



  });
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

路由app.use(app.router); 之前,您可以定义回调,在这种情况下,我搜索lang并在cookie中定义它。添加dynamicHelper以将Dicto对象包含到模板中后:

app.dynamicHelpers({

  i18n: function (req,res) {
      return new i18n({lang: req.lang});
  }

});

在路由之前定义lang。 (保存在req.lang中),我现在可以使用模板中的i18n halper(带玉):

form.uniForm(action="/account",method="post")
    fieldset.inlineLabels
        .ctrlHolder
            label(for="nickname") #{**i18n.getText('user:nick')**}:
            input(type="text",name="nickname",value=everyauth.user.nick)
            p.formHint

i18n对象现在与动态助手上的定义相同。

答案 1 :(得分:0)

据我了解,express只会调用一次辅助函数(当编译模板时......)

在快速指南http://expressjs.com/guide.html中,查看对您的情况更有用的dynamicHelpers(dynamicHelpers提供请求和响应对象)。