【问题标题】:Dynamic (i18n) links using expressjs and jade使用expressjs和jade的动态(i18n)链接
【发布时间】:2012-02-05 02:16:25
【问题描述】:

我正在使用 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”链接实际上应该是“/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写的

执行此操作的首选方法是什么?我一直在寻找和寻找,但无法找到一个好的答案..

这其实也是一个笼统的问题;即如何链接到其他内部内容,例如 Rails 中的 link_to。仅仅做 a(href="someAction") 是不够的,因为你希望它生成绝对 URL,这样漂亮的 URL 就不会破坏静态内容链接。

谢谢!

【问题讨论】:

    标签: javascript node.js internationalization express pug


    【解决方案1】:

    我使用 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'));
    });
    

    routing 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 对象现在与动态帮助器上定义的对象相同。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 2016-11-11
        • 2013-03-15
        • 1970-01-01
        • 2011-05-08
        相关资源
        最近更新 更多