playframework 2.0 - Play Framework 2 - Different views for different devices -
playframework 2.0 - Play Framework 2 - Different views for different devices -
i'm building play 2.1.0 (java) app needs have 2 different versions: desktop web app , mobile web app. i'm looking way doesn't modify controllers' logic, relies on routing. ideal behaviour should be:
routes same desktop , mobile controllers same desktop , mobile views different mobile , desktop, share naming convention.is there somewhere can hookup routing behaviour and, say, append .mob view name rendered view main.scala.html
desktop , main.scala.mob.html
mobile? ideal, since controllers need no changes (or ugly ifs) , each view needs have it's own mobile version. guess need request @ point perform device detection. cooler if fallback desktop view if no mobile view implemented specific action.
any ideas?
thanks, gonzalo
i ended composing actions needed mobile version action. accomplish that, created @mobile
runtime annotation used annotate these actions name of mobile view. annotated actions composed next mobileaction
, performs device detection:
public class mobileaction extends action<mobile> { public mobileaction() { } public mobileaction(mobile configuration, action<?> delegate) { this.configuration = configuration; this.delegate = delegate; } @override public result call(http.context ctx) throws throwable { final http.request request = ctx.request(); final string useragent = request.getheader("user-agent"); // see https://developer.mozilla.org/en-us/docs/browser_detection_using_the_user_agent if (useragent.contains("mobi")) { ctx.args.put("viewname", configuration.value()); } homecoming delegate.call(ctx); } }
the implemented dynamicrendered
class looks viewname
argument (optionally injected @mobile
) , uses reflection render appropriate view.
public class dynamicrenderer { public static html render(string viewname, object... args) { final map<string, object> ctxargs = http.context.current().args; final string view = ctxargs.containskey("viewname") ? ((string) ctxargs.get("viewname")) : viewname; // argument classes final class[] argclasses = new class[args.length]; (int i=0; i<args.length; i++) { argclasses[i] = args[i].getclass(); } seek { // view render method , invoke final class<?> clazz = class.forname(view); final method render = clazz.getdeclaredmethod("render", argclasses); final html html = ((html) render.invoke(null, args)); homecoming html; } grab (classnotfoundexception e) { e.printstacktrace(); } grab (nosuchmethodexception e) { e.printstacktrace(); } grab (invocationtargetexception e) { e.printstacktrace(); } grab (illegalaccessexception e) { e.printstacktrace(); } homecoming null; } }
then, instead of calling ok(viewname.render(...))
in controller, phone call ok(dynamicrenderer.render("viewname", ...))
playframework-2.0
Comments
Post a Comment