branaway / japid Goto Github PK
View Code? Open in Web Editor NEWA Java-based statically-typed fast template engine that can be used in any Java code. It has special adapter for use with the Play! Framework.
A Java-based statically-typed fast template engine that can be used in any Java code. It has special adapter for use with the Play! Framework.
`tag ajax name="myAjax", url="/DTD/myAjax", data="{value:'my Name'}", \
reRender="#someDivId, .someClass|append", \
event="#otherDivId"
--> error: reRender param value contains |
[Japid] Transforming template: app\japidviews\backend\Admin\index.html to: index.java
java.lang.RuntimeException: the line does not seem to be a valid param declaration list: append", event="#otherDivId"
at cn.bran.japid.compiler.JavaSyntaxTool.parseParams(JavaSyntaxTool.java:88)
at cn.bran.japid.compiler.TagInvocationLineParser.parse(TagInvocationLineParser.java:52)
at cn.bran.japid.compiler.JapidAbstractCompiler.buildTagDirective(JapidAbstractCompiler.java:891)
at cn.bran.japid.compiler.JapidAbstractCompiler.doTagDirective(JapidAbstractCompiler.java:675)
at cn.bran.japid.compiler.JapidAbstractCompiler.script(JapidAbstractCompiler.java:428)
at cn.bran.japid.compiler.JapidAbstractCompiler.scriptline(JapidAbstractCompiler.java:313)
at cn.bran.japid.compiler.JapidTemplateCompiler.scriptline(JapidTemplateCompiler.java:110)
at cn.bran.japid.compiler.JapidAbstractCompiler.parse(JapidAbstractCompiler.java:137)
at cn.bran.japid.compiler.JapidAbstractCompiler.hop(JapidAbstractCompiler.java:824)
at cn.bran.japid.compiler.JapidAbstractCompiler.compile(JapidAbstractCompiler.java:91)
at cn.bran.japid.compiler.JapidTemplateTransformer.generate(JapidTemplateTransformer.java:131)
at cn.bran.japid.compiler.TranslateTemplateTask.execute(TranslateTemplateTask.java:141)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:224)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:289)
at cn.bran.play.JapidPlugin.beforeDetectingChanges(JapidPlugin.java:86)
at cn.bran.play.JapidPlugin.onLoad(JapidPlugin.java:49)
at play.plugins.PluginCollection.initializePlugin(PluginCollection.java:188)
at play.plugins.PluginCollection.loadPlugins(PluginCollection.java:120)
at play.Play.init(Play.java:276)
at play.server.Server.main(Server.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Exception in thread "Main Thread" java.lang.RuntimeException: java.lang.RuntimeException:the line does not seem to be a valid param declaration list: append", event="#otherDivId"
at cn.bran.japid.compiler.TranslateTemplateTask.execute(TranslateTemplateTask.java:145)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:224)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:289)
at cn.bran.play.JapidPlugin.beforeDetectingChanges(JapidPlugin.java:86)
at cn.bran.play.JapidPlugin.onLoad(JapidPlugin.java:49)
at play.plugins.PluginCollection.initializePlugin(PluginCollection.java:186)
at play.plugins.PluginCollection.loadPlugins(PluginCollection.java:120)
at play.Play.init(Play.java:273)
at play.server.Server.main(Server.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
`tag ajax name="myAjax", url="/DTD/myAjax", data="{value:'my Name'}", \
reRender="#someDivId, .someClass|append", \
event="#otherDivId" |
`
----> then we have other error:
Compilation error (In /app/japidviews/backend/Admin/index.java around line 163)
The file /app/japidviews/backend/Admin/index.java could not be compiled. Error raised is : ajax.DoBody cannot be resolved to a type
play.exceptions.CompilationException: ajax.DoBody cannot be resolved to a type
at play.classloading.ApplicationCompiler$2.acceptResult(ApplicationCompiler.java:246)
at org.eclipse.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:672)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:516)
at play.classloading.ApplicationCompiler.compile(ApplicationCompiler.java:280)
at play.classloading.ApplicationClassloader.getAllClasses(ApplicationClassloader.java:408)
at play.Play.start(Play.java:456)
at play.Play.detectChanges(Play.java:574)
at play.Invoker$Invocation.init(Invoker.java:187)
at Invocation.HTTP Request(Play!)
I know, as a workaround, i can put a ``doBody into tag definition, but this tag actually should not accept a body. Could i see it as a BUG? ^^ Thank you!
I see in the generated java codes that everywhere/everytime when a template is invoked, then a new instance of it is created, even when the same template is used twice within the same calling method (calling template). The following codes show it:
`set rightCol
`String myName = new String("tunggad");`
`Integer myNr = 80;`
<div>
<div id="editor"></div>
<div>
`tag myTemplate (arg2=29, arg1="tunggad", arg3=null)
</div>
`tag templateWithBody ("kkkk", myName, myNr) | String name, Integer nr
This is the body
`tag myTemplate (arg1=name, arg3=true, arg2=nr)`
`tag noParamsTemplate`
`
</div>
`
@Override protected void rightCol() {
final myTemplate _myTemplate4 = new myTemplate(getOut());
{ _myTemplate4.setActionRunners(getActionRunners()); }
final templateWithBody _templateWithBody5 = new templateWithBody(getOut());
{ _templateWithBody5.setActionRunners(getActionRunners()); }
final myTemplate _myTemplate6 = new myTemplate(getOut());
{ _myTemplate6.setActionRunners(getActionRunners()); }
final noParamsTemplate _noParamsTemplate7 = new noParamsTemplate(getOut());
{ _noParamsTemplate7.setActionRunners(getActionRunners()); }
// line 8
String myName = new String("tunggad");// line 10
Integer myNr = 80;// line 11
p(" <div>\n" +
" <div id=\"editor\"></div>\n" +
" <div>\n" +
" ");// line 11
_myTemplate4.render(named("arg2", 29), named("arg1", "tunggad"), named("arg3", null));
// line 15
p(" </div>\n" +
" ");// line 15
_templateWithBody5.render("kkkk", myName, myNr, new templateWithBody.DoBody<String, Integer>(){
public void render(final String name, final Integer nr) {
// line 17
p(" This is the body\n" +
" ");// line 17
_myTemplate6.render(named("arg1", name), named("arg3", true), named("arg2", nr));
// line 19
_noParamsTemplate7.render();
// line 20
}
}
);
// line 17
p(" </div>\n" +
" ");// line 21
;
}
Actually, the tow instances _myTemplate4 and _myTemplate6 could/should be reused?
BTW: Im just thinking abit futher, we see very often, that some representation logics actually only do READ-access to the passed paremater, and it would be a futher enorm optimization if we had something like STATIC TEMPLATE. They dont have own states, --> should be Thread-safe. They only have a static render method, where one can pass the parameter into, just like a static utils/service method. So we can reuse such static templates globally --> save cpu cycle for instances creation, save ram.
What do you think?
There's an extra newline added at the beginning of compiled template.
@(String name)
Hello $name
becomes
p("\n" +
"Hello ");// line 1
p(name);// line 2
I suppose this might be the newline after param list declaration, but as there must be newline after this declaration, it should be ignored.
The engine might be used to render other outputs then html, where whitespace is important.
Is there any way to use japid in play-scala?
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
some interesting ones:
-XX:+UseCompressedStrings Use a byte[] for Strings which can be represented as pure ASCII. (Introduced in Java 6 Update 21 Performance Release)
-XX:+OptimizeStringConcat Optimize String concatenation operations where possible. (Introduced in Java 6 Update 20)
-XX:+UseStringCache Enables caching of commonly allocated strings.
Hi,
Great work on the module. However I have a big problem that's preventing me from upgrading to the latest 0.9.4.3.
Inside my controller, I'm making some final checks on the request parameters trying to see if I need to return a jsonp response. If so, I would've simply done something like:
JapidResult jR = new JapidResult(getRenderResultWith(template(), stuffToRender));
StringBuilder res = jR.getRenderResult().getContent();
res.insert(0, "(").insert(0, callback).append(")");
throw jR;
But now, the RenderResultPartial sends back a new StringBuilder upon every access so my method obviously fails.
It would be optimal to always return the original StringBuilder, and not just enhance a new one every time getContent() is called.
When using Japid in the standonline mode, call japid gen will generate default directory structure including an empty _layouts and _tags folder. The generated java code has the following 2 import statements:
import japidviews .tags.;
import japidviews .layouts.;
if I don't have anything put into the _layouts and _tags folder, the compiler will complaint that
compile:
[javac] Compiling 1 source file to T:\tmp\template-engine-benchmarks\java\classes
[javac] T:\tmp\template-engine-benchmarks\java\src\japidviews\stocks.java:6: package japidviews._tags does not exist
[javac] import japidviews.tags.;
[javac] ^
[javac] T:\tmp\template-engine-benchmarks\java\src\japidviews\stocks.java:7: package japidviews._layouts does not exist
[javac] import japidviews.layouts.;
[javac] ^
[javac] 2 errors
Something like this is would be nice:
@args String arg1, Integer arg2=0, Boolean arg3=false
This is a String = <span style="color: green;">'${arg1}'</span>
and this an Integer = <span style="color: blue;">~{arg2 + 1}</span>
and Boolean = <span style="color: #ff0000;">'${!arg3}'</span>
`args String arg1, Integer arg2
This is a String = '${arg1}' and this is an Integer = ~arg2
`set leftCol
`
`set rightCol
`
Compilation error (In /app/japidviews/Application/admin.java around line 90)
The file /app/japidviews/Application/admin.java could not be compiled. Error raised is : _myTemplate24 cannot be resolved
play.exceptions.CompilationException: _myTemplate24 cannot be resolved
at play.classloading.ApplicationCompiler$2.acceptResult(ApplicationCompiler.java:246)
at org.eclipse.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:672)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:516)
at play.classloading.ApplicationCompiler.compile(ApplicationCompiler.java:280)
at play.classloading.ApplicationClassloader.getAllClasses(ApplicationClassloader.java:408)
at play.Play.start(Play.java:456)
at play.Play.detectChanges(Play.java:563)
at play.Invoker$Invocation.init(Invoker.java:187)
at Invocation.HTTP Request(Play!)
also tried to put the myTemplate2.html in _tag folder or to invoke using full path name ---> same error
I was trying to evaluate Japid for use in a new Play! based project.
I simply created a new Play project
play new japid
And added this dependency:
require:
- play
- play -> japid 0.8.3.1
And then started the SampleApp
cd modules/japid-0.8.3.1/JapidSample
play run
The home page can't find any of the Japid classes
Compilation error (In /app/controllers/Application.java around line 31)
The file /app/controllers/Application.java could not be compiled. Error raised is : JapidController cannot be resolved to a type
play.exceptions.CompilationException: JapidController cannot be resolved to a type
at play.classloading.ApplicationCompiler$2.acceptResult(ApplicationCompiler.java:246)
at org.eclipse.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:672)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:516)
at play.classloading.ApplicationCompiler.compile(ApplicationCompiler.java:278)
at play.classloading.ApplicationClassloader.getAllClasses(ApplicationClassloader.java:406)
at play.Play.start(Play.java:453)
at play.Play.detectChanges(Play.java:563)
at play.Invoker$Invocation.init(Invoker.java:186)
at Invocation.HTTP Request(Play!)
^C~ ...
First of all, I would like to thank you for such a great project!
I've got idea for small improvement: currently html produced by templates contains all whitespaces that where present in template, making it 2-3 times bigger than actual content. Idea is to introduce configuration option that will strip those whitespaces.
Removing them from template source is not an option as they are used as part of code stile, and sometimes simplify debug process, but in our production environment we have no way to compress traffic and thus 60% of our traffic are whitespaces.
This could be done in compile phase in prod mode, or just controlled by configuration option.
Today i came across this blog http://kaioa.com/node/59, ther author was talking about the performance impact of setting init-capacity for StringBuilder. I quote here the important observation of the author:
"If you take a closer look you can also see that there is some kind of rhythm: the best initial capacities (local optimum) are always a power of two. And the worst results are always just before the next power of two. The perfect results are of course achieved if the required size is used from the very beginning (shown as dashed lines in the diagram) and no resizing happens at all."
And i come to the idea how we can optimize the performance of Japid abit futher. Now we hardcode init-capacity of StringBuilder in constructor of JapidTemplateBaseWithoutPlay. My idea is to have a global tracking mechanism of the actual required size of each template and after a warmup the JapidTemplateBaseWithoutPlay constructor will lookup the ideal init-capacity for each template here.
What do you think?
Manual process is error-prone.
the command can be used:
play japid:mkdir
It'll create the app/japidviews/* tree
Hi, Bing.
I have a template named a.html:
{#get 'css' /}
As i know, it will be compiled as a abstract class with a abstract method css(). I want make a template b.html to extends a.html, like this:
{#get 'css' /}
{#get 'js' /}
When i try to get it work, an error occurs: "The abstract method css in type a can only be defined by an abstract class." Then I look at the b.java. The class b is not abstract. Could you support a way to define class as abstract? Simple way like add a line to top `abstract.
Thanks.
Hi and thank you for great plugin.
I faced the following issue. I have the 'for' loop and want to break it(use 'break' keyword) like following:
for Ingredient ingredient: ingredients
ingredient.product.get();
if (_index < 4 || ingredients.size() == 4) {
} else if (_index == 4){ <li>...</li>
} else {break;
}AFAIK 'for' loop generates render method callback. How can I break it ?
Thanks.
It requires a small change in the Play class, which is being considered by Play developers.
My local copy works well.
I found when japid convert a template to a java class, it always uses the file name directly. For example:
SampleLayout.html =======> SampleLayout.java
hello.html =======> hello.java
ask_question.html =====> ask_question.java
This will force us to use template names as "Hello.html", "AskQuestion.html", but I prefer to use "hello.html" and "ask_question.html" for file names.
Will japid make a convertion when generate file names? Automatically convert "abc" to "Abc" and "ab_cd" to "AbCd" ?
When I wrote:
<script src="@@{/public/javascripts/jquery-1.6.1.min.js}"></script>
In my page, it reports:
Execution exception
RuntimeException occured : error in running the renderer: No route found
public class Articles extends JapidController {
17:
18: public static void write() {
19: renderJapid(); // THIS LINE
20: }
From this report, I don't know what exactly happened. Finally, I found the I should declare the script as:
@@{'/public/javascripts/jquery-1.6.1.min.js'}
This is really not easy to find the reason from the error message, I think it should be improved.
With the new japidroot approach, the compiled template class files are not created within app path when we create WAR. And so, it doesn't work in Tomcat. Any documentation on this might be helpful.
String 类型的参数默认值不是 null,而是 ""。这是一个 bug 吗?
When I installed japid eclipse plugin, there is a "SampleLayout.html" generated. I tried to delete it, but it's automatically restored.
How to really delete it?
I have very simple hello world paly+japid app on GAE. The problem I have is when I refresh the page over a couple of minutes it takes about 7 seconds to load the page. It looks like not a GAE issue as the instance is still active on the gae admin console. I also tried rythm and rythm does not have this issue (it does take more time to load a page for real cold start since it does not have a precompile template.) please take a look.
Regards,
Bendanpa
My initial work is for 1.1. But nothing specific to 1.1 is required except for the module provisioning.
`String value = "something";
`String anotherValue = "Hello ${something}, im a another value";
Handy to use and save us alot of string-concats and the view codes look then abit like "view code" rather than coding view in Servlet :-D, if u know what i mean.
PS: pls also note the ability to escape the tow symbols $ and ~ .
After deploying to GAE using the GAE module with Japid I receive the following exception at startup. I ran japid:regen before deploying. I'm using Japid 0.8.4.3.
Failed startup of context com.google.apphosting.utils.jetty.RuntimeAppEngineWebAppContext@114a306{/,/base/data/home/apps/test/2.351048128178089005}
java.lang.RuntimeException: java.security.AccessControlException: access denied (java.io.FilePermission app/japidviews/_javatags write)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:200)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:289)
at cn.bran.play.JapidPlugin.beforeDetectingChanges(JapidPlugin.java:66)
at cn.bran.play.JapidPlugin.onLoad(JapidPlugin.java:45)
at play.plugins.PluginCollection.initializePlugin(PluginCollection.java:186)
at play.plugins.PluginCollection.loadPlugins(PluginCollection.java:120)
at play.Play.init(Play.java:273)
at play.server.ServletWrapper.contextInitialized(ServletWrapper.java:71)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:191)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:168)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:123)
at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:260)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$2.handleRequest(RuntimePb.java:9669)
at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:439)
at com.google.net.rpc.impl.Server$RpcTask.runInContext(Server.java:573)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:448)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:688)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:326)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:318)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:446)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Caused by: java.security.AccessControlException: access denied (java.io.FilePermission app/japidviews/_javatags write)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:355)
at java.security.AccessController.checkPermission(AccessController.java:567)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:45)
at java.lang.SecurityManager.checkWrite(SecurityManager.java:979)
at java.io.File.mkdir(File.java:1233)
at java.io.File.mkdirs(File.java:1262)
at cn.bran.play.JapidCommands.mkdir(JapidCommands.java:54)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:198)
... 28 more
In Groovy we have """multi-line String literale goes there""". So it would be nice when we had something like that:
@ String value = """line 1
line 2
line 3 ...
"""
@
Its very handy to use and save uns much of string-concats. It should also be possible in script block %{...}%
`import com.mongodb.DBObject;`
`import com.mongodb.util.JSON;`
`( List<DBObject> dtdList )
<ul>
`for DBObject dtd : dtdList
<li>
<h5 class='hideshowDTD {index:$_index}'>${dtd.get("package") + "." + dtd.get("name")}</h5>
<p id='json_$_index' class='hide'>${JSON.serialize(dtd)}</p>
<div class='align_right'>
<a href='#' class='loadDTD {index:$_index}'>load</a> |
<a href='#' class='hideshowDTD {index:$_index}'>hide/show</a>
</div>
</li>
`
</ul>
@Override protected void doLayout() {
...
_Each0.render(dtdList, new Each.DoBody<DBObject>(){
public void render(final DBObject dtd, final int _size, final int _index, final boolean _isOdd, final String _parity, final boolean _isFirst, final boolean _isLast) {
// line 7
p(" <li>\n" +
" <h5 class='hideshowDTD {index:");// line 7
p(_index);// line 9
p("}'>");// line 9
p(dtd.get("package") + "." + dtd.get("name"));// line 9
p("</h5>\n" +
" <p id='json_");// line 9
p(_index' class='hide'>${JSON.serialize(dtd)}</p> // HERE THE PROBLEM BEGINs
<div class='align_right'>
<a href=');// line 10
p("#' class='loadDTD {index:");// line 12
p(_index);// line 12
p("}'>load</a> |\n" +
" <a href='#' class='hideshowDTD {index:");// line 12
p(_index);// line 13
p("}'>hide/show</a>\n" +
" </div>\n" +
" </li>\n" +
" ");// line 13
}
}
);
// line 7
p(" </ul>");// line 16
}
}
当再次刷新页面时,后续的PlayPlugin 执行 onApplicationStart()才能继续进行
Oops: NullPointerException
An unexpected error occured caused by exception NullPointerException: null
play.exceptions.UnexpectedException: Unexpected Error
at play.Invoker$Invocation.onException(Invoker.java:244)
at play.Invoker$Invocation.run(Invoker.java:286)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException
at cn.bran.play.JapidPlugin.buildRoutes(JapidPlugin.java:511)
at cn.bran.play.JapidPlugin.onRoutesLoaded(JapidPlugin.java:554)
at play.plugins.PluginCollection.onRoutesLoaded(PluginCollection.java:669)
at play.mvc.Router.load(Router.java:51)
at play.mvc.Router.detectChanges(Router.java:219)
... 1 more
The design of Japid is that all templates MUST be in templateRoot/japidviews subfolder.
JapidRenderer.refreshClasses() method scans everything in templateRoot, thus iterates also over other html files that don't belong to Japid. This throws StringIndexOutOfBoundsException in JapidRenderer.getClassName()
The layout and general template can be /should be unified.
I have tested playclipse version 0.8.8.17 on Eclipse 3.7 JEE Edition, the configuration of HTML Editor seems to be ignored. I have my own color scheme for the Eclipse's HTML Editor, and it seems to be, that its configuration overwrite that of playclipse's HTML Editor.
Is this behavior to be expected so?
We are trying to deploy a Play application WITHOUT the source code.
So the steps are:
Problem is that Japid can't seem to find the classes anymore which have been compiled to the "precompiled" directory.
I created a "header.html", how to include it in every page?
I can do this in play as "#{include "header.html" /}", but how to do the same in japid?
In my template, I have this code:
<a href="@{Pages.xxx}">Edit</a>
which "Pages.xxx" in not existed. When I refresh the browser, it will report this error message:
Execution exception
RuntimeException occured : error in running the renderer: No route found In /app/controllers/Pages.java (around line 39)
35: }
36:
37: public static void show(Long id) {
38: Page page = Page.findById(id);
39: renderJapid(page);
40: }
41: }
But from the message, I can't find any information about the "Pages.xxx", it's not easy to look for it in the template.
I think it's better to provide the action name and the line number of template in the error message.
@if (allPost.size() > 0 ) {
The real title is: $title;
There is no post at this moment
在项目中遇到一个问题:如果在模板中有一个循环,循环体中只做一件事:回调action。此时编译的结果不是所期望的,我将例子简化如下:
在controller中有两个action:
public class JapidTestController extends JapidController {
public static void view1() {
renderJapid();
}
public static void willBeTempalteInvoke() {
renderJapid();
}
}
view1 模板的代码如下:
can not be invoke? `for(int i=0; i<10; i++){ `a JapidTestController.willBeTempalteInvoke() `}此时view1模板的编译结果为:
@OverRide
protected void doLayout() {
//------
p("\n" +
"\n" +
"\n" +
"can not be invoke?\n");// line 1
for (int i = 0; i < 10; i++) {// line 5
------期望这里出现回调,可是没有--------------------------
}// line 7
p("\n" +
"\n");// line 7
}
Hi, I am a Japid user. When I try to use Japid to resolve a tree, i found it's doesn't support recursion invoke a tag.
code example:
nodeTag.html:
`args TreeNode node
`if(!node.getChildren().isEmpty())
`{
#{Each node.getChildren() | TreeNode child}
#{nodeTag child /}
#{/}
`}
It will make a stack over flow exception.
Hi,
Play introduced a #{jsRoute} tag in 1.2.4 (see http://www.playframework.org/documentation/1.2.4/tags#jsroute). The corresponding commit is playframework/play1@02d4176e4e0422765b1e97.
It would be great to include a jsRoute static method in the JapidPlayAdapter (https://github.com/branaway/Japid/blob/master/src.japidplay/cn/bran/play/JapidPlayAdapter.java).
In addition, the RouteAdapter (https://github.com/branaway/Japid/blob/master/src.japidplay/cn/bran/play/RouteAdapter.java) should probably provide a method to obtain an ActionDefinition object as it's created in the lookup() method.
The JapidPlayAdapter can then, as it can be seen in the Play commit above, use the ActionDefinition object in the new jsRoute static method.
Having that would make a switch from the Groovy templating engine to Japid much easier. No javascript code would have to be modified.
Sorry for not providing you with a pull request. I thought setting up the Japid project locally and changing the code takes much longer than letting you do it with the information provided in this issue.
Thanks,
Mike
With the current design, the tag definition site controls what can be passed into its body. The tag definition prescribes the signature of the of DoBody.render interface method, and the calling site have to implement it. This design has a advantage of to be full type safe at compile time, but it is very inflexible. Because at the time of the definition of the tags we usually dont know all possible arguments which should be passed in at later usages. Another situation is, when we only have compiled tags/templates (for example form Play! module) and the tags/templates author didnt envisage our possible usage before, what could we then do?
My recommendation is to let the DoBody.render interface method being GENERIC, so the calling sites can decide how to implement it, what they want to pass in themself. Such a desing is much more flexible and increases code reuse alot.
(First of all, sorry. I don't know where to report issues about your play! 1.2.x fork, so posting here.)
Your play! fork is very productive to get template errors and development speed. But, there's a problem with displaying errors in production mode (in our case with WAR).
When you get time, please share where to look for (which file) fixing these errors. Unfortunately, we couldn't able to figure it out yet. Thanks.
I have to so often call String.format in my Japid templates, so it would be nice, if we had a shortcut method for that, may be 'public static String f(String template, Object... args)' in JapidTemplateBaseWithoutPlay
. For the meantime i put this method in my own JapidWebUtil
.
&{'key.label'}
login: &{‘login.name’}
Exception in thread "main" cn.bran.japid.compiler.JapidCompilationException: : Message lookup commma
nd takes arguments like in a Java method call. Don't use single quotation marks to quote a message name for instance. 'key.label'
at cn.bran.japid.compiler.JapidAbstractCompiler.message(JapidAbstractCompiler.java:853)
at cn.bran.japid.compiler.JapidAbstractCompiler.parse(JapidAbstractCompiler.java:157)
at cn.bran.japid.compiler.JapidAbstractCompiler.hop(JapidAbstractCompiler.java:983)
at cn.bran.japid.compiler.JapidAbstractCompiler.compile(JapidAbstractCompiler.java:99)
at cn.bran.japid.compiler.JapidTemplateTransformer.generate(JapidTemplateTransformer.java:131)
at cn.bran.japid.compiler.TranslateTemplateTask.execute(TranslateTemplateTask.java:143)
at cn.bran.play.JapidCommands.reloadChanged(JapidCommands.java:140)
at cn.bran.play.JapidCommands.gen(JapidCommands.java:85)
at cn.bran.play.JapidCommands.main(JapidCommands.java:40)
Hi,
documentation is a bit old, is it possible to update it ?
my best
Serdar
How to check renderArgs in tests ? Can you show a sample code ?
I use standard renderArgs(String) but it doesn't work(empty).
The reason is open for loops are transformed to calling the each tag which requires a generic type, which cannot be a primitive.
Solution: change the element type to the corresponding object type at compile time.
I have a template that renders JSON like following:
`import com.mongodb.DBObject;
`( String msg, List<DBObject> dtdList )
{ "statusMsg" : "<span style="color: #ff0000;">${msg}</span>", // style=\"color: #ff0000;\" also does not work
"dtdList" : "`tag _dtdList(dtdList)`" }
this JSON String is returned for a AJAX request to partial-updade two fragment of the page. The problem is, when this JSON String arrives at client side, jQuery can't parse/evaluate it to a proper JavaScript JSON object, because the values within "..." cantain special charaters (", , etc.).
What i want to recommend is to add a util method for direct usage AND an option when invoking a tag which escape the special characters or HTML-encode the content so that the JSON String can be properly evaluated at client side.
As workaround for meanwhile i can write a util method by myself which does this job and give raw strings which i want to being HTML-encoded. But i will stuck, if i want to use template, because the render method will be called and it write the contents direct into stringbuilder, i dont get a chance to do some pre-processing before it gets written.
BTW: I was always doing this style of AJAX partical-update, when multiple page-fragments should be updated per AJAX. With Grails, i dont know, what for auto-magic the framework does underneath, but it always worked properly and i must not call escapse/encode explicitely. May be, because Grails has its own JSON builder, which handles all this job internally.
Now we only have positional parameter passing when calling tag. With simple tags with few parameter its ok, but when calling tags with many parameter it will very easy to gets confused. The semantic of the parameters are not immediate clear to the code reader/maintainer, what are being passed into the tag. I would recommend to add support for named parameter passing to tag-calling. Such a feature is very popular by all templating engine of the dynamic script languages.
I know, its abit trickier to implement this feature in pure Java. But it should be possible thanks reflection, should it? ^_^
I think its very helpful and important feature for a template engine, and hope you would see it so as well. Thank you Bing!
--- routes ---
GET /favicon.ico 404
Error Message:
Description Resource Path Location Type
Missing route: 404 routes /demo/conf line 10 Problem
With current syntax all passed parameter, named or positional, must be on same line with ``tag myTag ... But sometime we have to pass alot of parameters and they are long --> the invocation quickly becomes to look confused, not reader-friendly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.