CustomTemplate for Play 2.1 in Java #253

Closed
jezozwierzak opened this Issue Jul 27, 2013 · 13 comments

Comments

Projects
None yet
4 participants

First of all I would like to say I've seen site: http://securesocial.ws/guide/views-customization.html.
I've also seen many issues on github and stackoverflow. I still don't know how to customize views.

I tried create scala class in controllers package and fill it as in http://securesocial.ws/guide/views-customization.html example. Here is my implementation: http://pastebin.com/M6TGuUnR . I got error:

[info] Compiling 2 Scala sources to /home/jezozwierzak/repos/git/pawlaczek.eu/premiumCMS/target/scala-2.10/classes...
[error] /home/jezozwierzak/repos/git/pawlaczek.eu/premiumCMS/app/controllers/SecureViews.scala💯 overriding method getSignUpEmail in trait TemplatesPlugin of type (token: String)(implicit request: play.api.mvc.RequestHeader)(Option[play.api.templates.Txt], Option[play.api.templates.Html]);
[error] method getSignUpEmail has incompatible type
[error] def getSignUpEmail(token: String)(implicit request: RequestHeader): String = {
[error] ^
[error] /home/jezozwierzak/repos/git/pawlaczek.eu/premiumCMS/app/controllers/SecureViews.scala:133: overriding method getUnknownEmailNotice in trait TemplatesPlugin of type ()(implicit request: play.api.mvc.RequestHeader)(Option[play.api.templates.Txt], Option[play.api.templates.Html]);
[error] method getUnknownEmailNotice has incompatible type
[error] def getUnknownEmailNotice()(implicit request: RequestHeader): String = {
[error] ^
[error] /home/jezozwierzak/repos/git/pawlaczek.eu/premiumCMS/app/controllers/SecureViews.scala:22: class SecureViews needs to be abstract, since:
[error] it has 5 unimplemented members.
[error] /** As seen from class SecureViews, the missing signatures are as follows.
[error] * For convenience, these are usable as stub implementations.
[error] */
[error] def getAlreadyRegisteredEmail(user: securesocial.core.Identity)(implicit request: play.api.mvc.RequestHeader): (Option[play.api.templates.Txt], Option[play.api.templates.Html]) = ???
[error] def getNotAuthorizedPage[A](implicit request: play.api.mvc.Request[A]): play.api.templates.Html = ???
[error] def getPasswordChangedNoticeEmail(user: securesocial.core.Identity)(implicit request: play.api.mvc.RequestHeader): (Option[play.api.templates.Txt], Option[play.api.templates.Html]) = ???
[error] def getSendPasswordResetEmail(user: securesocial.core.Identity,token: String)(implicit request: play.api.mvc.RequestHeader): (Option[play.api.templates.Txt], Option[play.api.templates.Html]) = ???
[error] def getWelcomeEmail(user: securesocial.core.Identity)(implicit request: play.api.mvc.RequestHeader): (Option[play.api.templates.Txt], Option[play.api.templates.Html]) = ???
[error] class SecureViews(application: Application) extends TemplatesPlugin {
[error] ^
[error] three errors found
error Compilation failed
[error] application -

I can't figure out how to fix " has incompatible type" I think it's because I'm not to strong in scala. There is also error: "SecureViews needs to be abstract, since:
it has 5 unimplemented members", which I think tells that example on your website should be updated. Tell me if I'm wrong, please.

jezozwierzak

Contributor

magro commented Jul 27, 2013

To support multipart emails the return type of some methods changed from string to tuple of
Option[play.api.templates.Txt] and Option[play.api.templates.Html], written as (Option[play.api.templates.Txt], Option[play.api.templates.Html]). This change is merged in the master branch, but docs refer to an older version.

You can checkout the docs from master, they show the correct code: https://github.com/jaliss/securesocial/blob/master/docs/src/manual/source/guide/views-customization.md

Thx for fast tip. I'm checking it.

There are still errors in docs.
There should be replaced SocialUser to securesocial.core.Identity.
There also should be getNotAuthorizedPage method implemented.

Anyway I guess securesocial_repo/module-code/app/securesocial/views/ is good place to get example views, right?

Contributor

magro commented Jul 27, 2013

Am 27.07.2013 21:42 schrieb "jezozwierzak" notifications@github.com:

There are still errors in docs.
There should be replaced SocialUser for securesocial.core.Identity.
There also should be getNotAuthorizedPage method implemented.

Good catch! Do you want to submit a pull request for this? Otherwise I can
do this as well.

Anyway I guess securesocial_repo/module-code/app/securesocial/views/ is
good place to get example views, right?

Yes, should be right.

I will gladly do it.

Now I still can't make my custom views work. I got error:

play.api.Application$$anon$1: Execution exception[[RuntimeException: There is no HTTP Context available from here.]]

I read this https://groups.google.com/forum/#!msg/play-framework/EEY0-IK9rb8/loEIASG5A_EJ .
Now I think custom views should be implemented in java. Tell me if you can see other way to fix it.

Contributor

magro commented Jul 28, 2013

Please provide more information about your issue: at least controller code and the template. Otherwise it's hard to provide good help, e.g. I could just answer "no" ;-)

My login view code: http://pastebin.com/kpL3xtw8
My main view code: http://pastebin.com/y1SdRgMa

Login view is pointed out by my SecureViews included above.

More detailed error stack:

! @6f53ppenf - Internal server error, for (GET) [/admin/login] ->

play.api.Application$$anon$1: Execution exception[[RuntimeException: There is no HTTP Context available from here.]]
at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10-2.1.0.jar:2.1.0]
at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10-2.1.0.jar:2.1.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$12$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:314) [play_2.10-2.1.0.jar:2.1.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$12$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:312) [play_2.10-2.1.0.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10-2.1.0.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10-2.1.0.jar:2.1.0]
java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:30) ~[play_2.10-2.1.0.jar:2.1.0]
at play.mvc.Http$Context$Implicit.flash(Http.java:167) ~[play_2.10-2.1.0.jar:2.1.0]
at views.html.main$.apply(main.template.scala:222) ~[classes/:na]
at views.html.auth.login$.apply(login.template.scala:31) ~[classes/:na]
at controllers.SecureViews.getLoginPage(SecureViews.scala:32) ~[classes/:na]
at securesocial.controllers.LoginPage$$anonfun$login$1.apply(LoginPage.scala:52) ~[securesocial_2.10-master-SNAPSHOT.jar:master-SNAPSHOT]

I still think it should be written in Java ;P

Contributor

magro commented Jul 28, 2013

Ok, now I see that the issue is caused by the main template accessing flash.
I'd say implementing your custom TemplatesPlugin in java will not change anything, as you're still going through the securesocial.controllers.LoginPage which is a scala controller so there's no java HTTP Context bound.

So the main template sometimes needs to access the java flash scope and sometimes the scala one.
To achieve this it might be possible to access the flash data via a java.util.Map: the java version (play.mvc.Http.Flash) directly implements java.util.Map<String, String>, the scala version could be converted to a java Map via play.libs.Scala.asJava(play.api.mvc.Flash.serialize(request.flash)) (where request is of type play.api.mvc.Request, which is passed to TemplatesPlugin.getLoginPage).
So from other templates you could pass the flash directly to the main template (via s.th. like @main(flash), and from securesocial templates (that get passed the parameter request: play.api.mvc.Request[_] from your TemplatesPlugin) you could invoke the main template via @main(play.libs.Scala.asJava(play.api.mvc.Flash.serialize(request.flash))).

This might also be interesting to you:
http://stackoverflow.com/questions/16284299/custom-views-in-securesocial-in-java

An alternative to implementing the TemplatesPlugin in java would be to have a java and a scala version of the main template - just to mention it (of course not desireable).

Contributor

magro commented Jul 31, 2013

@jezozwierzak What do you think about the proposed solution?

I'll tell you on Tuesday. I'm on vacation till Monday. Sorry didn't say.

Contributor

magro commented Aug 3, 2013

Ok, no problem, enjoy the rest of your vacation!

Contributor

yankov commented Aug 18, 2013

@magro I fixed some of the bugs in example for customized views. I think people open similar issues because of the inaccurate example. Can you take a look?
#261

Owner

jaliss commented Jan 27, 2014

This should be fixed. Please re-open if you're still experiencing the problem.

jaliss closed this Jan 27, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment