2012-04-09 9 views
2

Kurzfassung: Gibt es eine attraktive, einfache Möglichkeit, eine sprachspezifische URL-Struktur zu implementieren, ala. host.com/de/ oder host.com/pt/ in Play 1.2.5?SEO freundliches Routing in Play

Ich bin auf der Suche nach einer Lösung, die nicht alle Controller ändern müssen, und die Änderung sollte vorzugsweise nur für die Routing-Datei sein, da ich nicht zwei Sätze von redundanten Ansichten - eine für jede Sprache will.

Ich habe bereits eine message.pt und message.en, und ich habe eine Möglichkeit, zwischen den beiden zu wechseln, aber ich bin ein Newb, wenn es um das Routing geht.

Ich weiß, dass die Routing-Datei eine Route enthalten kann wie: "/ (en | pt) /" aber ich bin hier irgendwie fest.

Ich applies, wenn die Frage ein bisschen vage ist. Ich werde gerne klären, sollte sich die Notwendigkeit ergeben.

+0

Haben Sie versucht, etwas Ähnliches wie das Tutorial definiert, welche Aufgabe zu rendern? Etwas in der Art von 'POST/tasks /: id/delete controllers.Application.deleteTask (id: Long)'. –

+0

Rahmenversion? – sdespolit

+0

Dan: Müsste ich dann nicht alle Controller ändern ?, um das Attribut lang zu akzeptieren? – DarkNeuron

Antwort

1

Ich fand eine Lösung in einigen alten Änderungshinweise für Play 1.1: http://www.playframework.org/documentation/1.2/releasenotes-1.1 (unter "Globale Route Argumente"). Seltsam, dass es nirgendwo sonst erwähnt wird.

[Bearbeitet, um die gesamte Arbeitslösung enthalten] [Edit2 - Ein Problem wurde behoben]

Meine Routen-Datei sieht wie folgt aus:

# Home page 
GET  /{lang}/?       Application.index 
GET /         Application.redirect 
GET  /{lang}/woops/?      Application.underConstruction 

Die Sprache Controller wie diese atm aussieht:

public class Language extends Controller { 

@Before 
static void detectLangInURL() { 
    String url = request.url; 

    if (url.length() > 2 && isSupported(getFromUrl(url))) 
    { 
     String lang = getFromUrl(url); 
     if (!Lang.get().equals(lang)) { 
      Lang.change(lang); 
      response.setCookie("lang", lang, "60d"); 
     } 
     renderArgs.put("lang", Lang.get()); 
     routeArgs.put("lang", Lang.get()); 
    } 
} 

private static String getFromUrl(String url) { 
    String[] s = url.split("[/]"); 
    if (s.length > 1) 
     return s[1]; 
    else return ""; 
} 

private static boolean isSupported(String lang) { 
    if (lang.length() == 0) 
     return false; 

    String[] langList = Play.configuration.get("application.langs").toString().split(","); 
    for (int i = 0; i < langList.length; i++) { 
     if (langList[i].compareToIgnoreCase(lang) == 0) 
      return true; 
    } 

    return false; 
} 
} 

Die Umleitungsmethode sieht folgendermaßen aus:

public static void redirect() { 
    Cookie lang = request.current().cookies.get("lang"); 
    if (lang != null && !lang.value.isEmpty()) 
     Lang.change(lang.value); 
    redirect(Lang.get() + "/"); 
} 

Ich musste wählen, ob ich eine @With(Language.class) Annotation verwenden oder die Controller Super Klasse ändern wollte. Ich wähle die @With Annotation.

Ich bin zufrieden, es endete damit, ziemlich einfach zu sein. Ich hoffe, dass jemand von den oben genannten profitieren kann.

1

Ich glaube nicht, dass es einen Weg gibt, um etwas zu tun, müssen Sie etwas zu Ihren Controllern tun.

Ich habe nicht aber etwas getestet wie das funktionieren sollte:

public static class LanguageParams extends Controller 
{ 
    @Before 
    static void addLanguageParam(String language) 
    { 
     renderArgs.put("lang", language); 
    } 
} 

Sie müssen hinzufügen @With zu jedem Controller wie folgt aus:

@With(LanguageParams.class) 
public class Foo extends Controller 
{ 
.... 
} 

... und in Ihrem Route würden Sie so etwas wie dieses:

GET foo/{<en|pt>language>}/whatever  Foo.index() 

Während dies kam es mir in den Sinn schreiben, dass Sie in der Lage sein kann zu tun dies mit einem Plugin, siehe: http://www.playframework.org/documentation/api/1.2/play/PlayPlugin.html#beforeActionInvocation(java.lang.reflect.Method)