Giter Site home page Giter Site logo

rythm-doc's Introduction

Rythm Template Engine

APL v2 Maven Central Javadocs Get Support on StackOverflow

A "Razor" like, rich featured, high performance and easy to use Java template engine

Rythm Engine Project

Join the chat at https://gitter.im/greenlaw110/Rythm

We are looking for people to join us on this project. Please contact Green Luo via [email protected]

Links

Integrations

Prerequisites

Java JDK >= Version 7

Distribution

Available at Maven Central see

http://mvnrepository.com/artifact/org.rythmengine/rythm-engine

Maven dependency:

<!-- http://mvnrepository.com/artifact/org.rythmengine/rythm-engine -->
<dependency>
    <groupId>org.rythmengine</groupId>
    <artifactId>rythm-engine</artifactId>
    <version>1.3.0</version>
</dependency>

How to build

git clone https://github.com/rythmengine/rythmengine
cd rythmengine
mvn install

if some of the tests should fail you might want to file an issue and try

mvn install -DskipTests=true

Testing

mvn test
...
Tests run: 254, Failures: 0, Errors: 0, Skipped: 3

Development

There are several options for development environments you can use to contribute to the development of the Rythm Engine Project:

Version history

See the change log

rythm-doc's People

Contributors

davidepastore avatar dtelaroli avatar greenlaw110 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rythm-doc's Issues

Support loading templates from resources

As of today it's only possible to use either inline templates (Strings) or template files. There's no way to use templates stored in the resources, though in some cases this could have been a good option. One example is Spring Boot and its Spring Boot Gradle Plugin. Briefly, they build a fat executable JAR that has all the dependencies, servlet container and, sure, resources. So, to have your web app up, you just run this JAR.

One workaround I can think of, is to extract templates from resources to a temporary folder and then configure Rythm work with this folder. But this approach feels slightly ugly.

one page Developer's Guide

It would be good to have all Developer's Guide in one page (it's easer to use, able to search in it, and just have it open like a cheat sheet)

通用性

通用性

Rythm被设计为通用模版引擎,可以生成html页面,xml文件,各种源代码,SQL脚本,电子邮件以及任何基于文本的内容。

这时是否还应该强调,rythm可在任何java程序中使用,而不依赖某一个特定的框架。

使用ant来演示程序,感觉有点不太习惯

一般都是直接给出代码,让用户自己在IDE里跑就行了。使用ant的方式,总觉得有点奇怪,让人觉得“是不是只能用ant才能用rythm啊?我想在java程序里直接用行不行啊“

可以给那些参数提供默认值以及代码方式的配置,演示的时候直接用默认值,需要修改的时候,也可以在代码中直接进行(给个示例即可)。

有一段代码应该加点解释

<p>@i18n("template", "planet", 7, new Date())</p>

看到后面也不明白多个参数是怎么回事,另外最好把资源文件中相应内容也加上。

Template Render issue

I just add a template like this :
public void set @Fieldname(String field)
{
this.@Fieldname = field;
}
public String get@fieldName()
{
return this.@Fieldname;
}
when I run it, it will throws some errors like:
Exception in thread "main" org.rythmengine.exception.CompileException: Syntax error on token "field", delete this token

Template:
public void set @Fieldname(String field)
{
this.@Fieldname = field;
}
public String get@fieldName()
{
return this.@Fieldname;
}

Relevant template source lines:

1:

2: public void set @Fieldname(String field)
3: {
4: this.@Fieldname = field;
5: }
6: public String get@fieldName()
7: {
8: return this.@Fieldname;

Relevant Java source lines:

42:
43: @OverRide public org.rythmengine.utils.TextBuilder build(){
44: buffer().ensureCapacity(180);
45: p("\npublic void set "); //line: 2
46:

47: try{pe(fieldName(String field));} catch (RuntimeException e) {__handleTemplateExecutionException(e);} //line: 2
48: p("\n{\nthis."); //line: 4
49:
50: try{pe(fieldName);} catch (RuntimeException e) {__handleTemplateExecutionException(e);} //line: 4
51: p(" = field;\n}\npublic String get"); //line: 6
52:
53: try{pe(fieldName());} catch (RuntimeException e) {__handleTemplateExecutionException(e);} //line: 6

Any one can help me ?

国际化里,怎么处理金额的转换?

Date: 11 March 2013
Amount: $20000.00

或者

日期:2013年3月11日
金额:¥20000.00

如果仅替换金额符号,可能会产生问题,比如同样的东西,在美国卖1000美元,在**就成了1000人民币。

是否应该提供一些方法,让金额在转换时有机会对数值也进行改变?

“替换模式”这块很难读

Rythm为这种情况提供了一个名为“替换模式”的运行环境。这种方式可以完全避免由于运行不信任模版代码带来的担忧,因为该模式仅仅运行变量值替换,而所有可能带来不安全因素的特性都被屏蔽了,其中包括 表达式运算, 脚本 和 自由循环 等。运行“替换模式”的API是:

感觉像是机器翻译的。另外从这段描述中,没有看到哪儿有“替换”

Disable smart escaping

It seems disabling of smart escaping doesn't work.

I'm using the following code:

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("feature.smart_escape.enabled", false);
    RythmEngine engine = new RythmEngine(map);
    System.out.println(engine.conf().smartEscapeEnabled()); // false

    String main = engine.render(".\\src\\main\\resources\\templates\\test.html", "Rythm", "line 1 <br> line 2");

Where test.html is simple html template.

Output contains: line1 & lt ; br & gt ; line 2

But I need the following output: .... line1 <br> line 2 ....

Is this is a bug? If no, please advice how to disable smart escaping. Maybe I need to configure some another parameters?

How to call user defined method with 2 parameter in template

I successfully call the method that have 1 parameter but How to call user defined java method with 2 parameter in template like
i have a method -:

static String test(Object obj,String str){
//to do
}

how i call this method in rythm template .

please tell me asap..
Thanks

错别字或一些词语

url: http://rythm.greenlaw110.com/doc/tutorial.md#hello

"这是一位Rythm没有找到一" -> 改为“这是因为”
"当用户需要改变是也能说" -> "当用户需要改变时也能说"
”机器上安装好了一下软件“ -> "机器上安装好了以下软件"

http://rythm.greenlaw110.com/doc/feature#developer-friendly

"事实胜于雄辩,让我们...:" 似乎改为 ”用代码说话“更流畅一些,仅供参考
"包括注释,流控,输出变量" -> "流控“有点不好理解,改为”流程控制“
”应当让Java程序员感觉是本土语言“ -> “应当让Java程序员感到亲切”
“当运行于开发模式时,Rythm重新解析编译变动了的模版文件,” -> “在开发模式下,如果模板文件被修改了,则rythm会自动重新解析、编译并把它载入到classloader中“
”你几乎不会注意到时延“ -> "你几乎不会注意到有延时"
“这是最常用的也是最强大扩充模版库的办法。Rythm允许用户在一个模版中以调用Java方法的模式来调用另一个模版。” -> "这是最常用最强大的扩充模版库的办法。Rythm允许用户在模版中把另一个模板当作一个java方法来调用。"
“注意如果Rythm运行在沙箱模式下,模版的执行会比普通情况多花大约40%的时间。” -> "在沙箱模式下,rythm的执行速度会降低约40%"

总体觉得文字不够精炼,像是翻译过来的。

使用np.pair似乎比用map更长

Map version:

import java.util.*;
import com.greenlaw110.rythm.Rythm;

public class HelloWorld {
    public static void main(String[] args) {
        Map<String, Object> params = new HashMap<String, Object>(2);
        params.put("who", "World");
        params.put("action", "Greeting");
        System.out.println(Rythm.render("helloworld.html", params));
    }
}

np version:

import java.util.*;
import com.greenlaw110.rythm.Rythm;
import com.greenlaw110.rythm.utils.*;

public class HelloWorld {
    public static void main(String[] args) {
        NamedParams np = NamedParams.instance;
        System.out.println(
            Rythm.render("helloworld.html", 
                np.from(
                    np.pair("who", "World"), 
                    np.pair("action", "Greeting"))));
    }
}

感觉后面比map版更长。

如果是我的话,我可能就直接定义一个方法了:

public static Map map(Object... params) {
   // 每次取两个参数当key/value,组成一个map返回
}

search missing in documentation pages

I was looking for try/catch today as in @try/@catch - i thought there was a feature like that but i couldn't find it. Unfortunately I also didn't find a search option. Also it would be good to have some interactivity in the pages like user comments. IMHO a Wiki might be better suited for the documentation. By the way - how did you realize the syntax highlighting?

Passing one parameter by position

Please add to the documentation that you can't pass one parameter by position.
I spent more than one hour trying to understand why my template produce NPE :)

Map<String, Source> sources = .....
Rythm.render("@args Map<String, Source> sources  .....",  sources);  // won't work

How to define a user-defined tag?

I need a self-defined tag in template, something like staticUrl, so I can use it like below:

<html>
<body>
<script src="@staticUrl(/js/jquery.js)"></script>
</body>
</html>

In staticUrl, some user-defined logic can be injected. Any API for that?

np.from(np.pari(...))能否简化?

np.from(
       np.pair("who", "World"), 
       np.pair("action", "Greeting"))

能否直接用:

np.pair("who", "world").pair("action", "greeting")

去掉前面的np.from

另外甚至再简化一点,直接:

np.pairs("who", "world",
            "action", "greeting")

Move documentation to a mediawiki

Hi Green,

i was just trying to create an issue on github
rythmengine/rythmengine#358
and wanted to link to the corresponding documentation page.

The documentation pages may look nice and all but I think that is not as important as a good search feature and other features that would readily be available if it would simply be based on a mediawiki site. If it was such a site I could also help maintain and edit it. With the current state of affairs I would have to file an issue for every single item and I think that is not worthwhile

Wolfgang

内联方法,宏等,需要例子

内联方法: 在模版中定义内联方法就如同定义一个Java方法一样简单

宏: 宏在解析时被处理,这是运行时最快的重用模版块的方法,但不能传递参数。

Include指令: 在当前位置插入另一个模版的内容。可以重用被插入模版的内联行数。

变换器: 输出Java变量结果时对其进行再处理,使用起来就像调用被处理变量的方法一样。

这几处我觉得很重要,但没有示例代码不好理解。

Is it ok on Android?

On Android, I got these exception: "Ljava/lang/RuntimeException; thrown while initializing Lorg/rythmengine/internal/dialect/SimpleRythm;" and "Ljava/lang/ExceptionInInitializerError; thrown while initializing Lorg/rythmengine/internal/dialect/DialectManager;"

在maven上找不到1.0-b6

<dependency>
    <groupId>com.greenlaw110.rythm</groupId>
    <artifactId>rythm-engine</artifactId>
    <version>1.0-b6-SNAPSHOT</version>
</dependency>

在search.maven.org上只能找到1.0-b5

Template file and compiled file not found when template is rendered at first time.

When I rendered my page the first time, a error was raised:

Request processing failed; nested exception is java.lang.RuntimeException: java.io.FileNotFoundException: /usr/local/apache-tomcat-7.0.53/temp/__rythm/usr_local_apache_tomcat_7_0_53_webapps_ROOT_WEB_INF_templates_golf_courseList_html__R_T_C__.java (No such file or directory)


root cause

java.io.FileNotFoundException: /usr/local/apache-tomcat-7.0.53/temp/__rythm/usr_local_apache_tomcat_7_0_53_webapps_ROOT_WEB_INF_templates_golf_courseList_html__R_T_C__.java (No such file or directory)
    java.io.FileOutputStream.open(Native Method)
    java.io.FileOutputStream.<init>(FileOutputStream.java:221)
    java.io.FileOutputStream.<init>(FileOutputStream.java:171)
    org.rythmengine.internal.compiler.TemplateClassCache.cacheTemplateClassSource(TemplateClassCache.java:190)
    org.rythmengine.internal.compiler.TemplateClass.refresh(TemplateClass.java:590)
    org.rythmengine.internal.compiler.TemplateClass.refresh(TemplateClass.java:435)
    org.rythmengine.internal.compiler.TemplateClass.<init>(TemplateClass.java:332)
    org.rythmengine.internal.compiler.TemplateClass.<init>(TemplateClass.java:315)
    org.rythmengine.internal.compiler.TemplateClass.<init>(TemplateClass.java:307)
    org.rythmengine.RythmEngine.getTemplate(RythmEngine.java:836)
    org.rythmengine.RythmEngine.getTemplate(RythmEngine.java:871)
    org.rythmengine.RythmEngine.render(RythmEngine.java:946)
    org.rythmengine.Rythm.render(Rythm.java:265)
    com.ctlok.springframework.web.servlet.view.rythm.RythmView.renderMergedTemplateModel(RythmView.java:28)
    org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
    org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:76)

When I refreshed the page, another error raised:

java.lang.RuntimeException: Error load template instance for /usr/local/apache-tomcat-7.0.53/webapps/ROOT/WEB-INF/templates/golf/courseList.html
    org.rythmengine.internal.compiler.TemplateClass.templateInstance_(TemplateClass.java:379)
    org.rythmengine.internal.compiler.TemplateClass.asTemplate(TemplateClass.java:396)
    org.rythmengine.internal.compiler.TemplateClass.asTemplate(TemplateClass.java:402)
    org.rythmengine.RythmEngine.getTemplate(RythmEngine.java:839)
    org.rythmengine.RythmEngine.getTemplate(RythmEngine.java:871)
    org.rythmengine.RythmEngine.render(RythmEngine.java:946)
    org.rythmengine.Rythm.render(Rythm.java:265)
    com.ctlok.springframework.web.servlet.view.rythm.RythmView.renderMergedTemplateModel(RythmView.java:28)
    org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)

The third time, the page rendered successfully. So, where is the possible reason for this?

@this directive not documented

I had an issue with recursive template invocation (see issue #363 and StackOverflow). It seems the @this directive is not officially documented anywhere, but it is used in this example.

It would have saved a lot of my time if it had been documented. Please, consider adding a proper section for this directive under Invoke Template or any other place of your documentation you see fit.

传递代码块给调用模板

传递代码块给调用模板

Rythm中除了能传递参数给调用模板,也能传递代码块,如下例所示:

@greenscript.js() {
$(function()) {...}
}

这个可以有具体的例子么.....怎么用的??

Rythm.render("helloworld.html", "World")

关于这个方法有点疑问,如果存在helloworld.html这个文件,则去渲染文件,不存在则当成普通字符串。

万一我希望把它当成普通字符串来渲染,但恰好那边有一些同名文件,怎么办?

要不弄成 Rythm.renderStr("...")来渲染字符串,或者Rythm.render(new File("..."))来渲染文件?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.