├── system.properties ├── src ├── main │ ├── webapp │ │ ├── ace │ │ │ └── src-min-noconflict │ │ │ │ ├── mode-text.js │ │ │ │ ├── snippets │ │ │ │ ├── d.js │ │ │ │ ├── ada.js │ │ │ │ ├── dot.js │ │ │ │ ├── ejs.js │ │ │ │ ├── ftl.js │ │ │ │ ├── ini.js │ │ │ │ ├── jsx.js │ │ │ │ ├── svg.js │ │ │ │ ├── xml.js │ │ │ │ ├── abap.js │ │ │ │ ├── glsl.js │ │ │ │ ├── haxe.js │ │ │ │ ├── jade.js │ │ │ │ ├── json.js │ │ │ │ ├── less.js │ │ │ │ ├── lisp.js │ │ │ │ ├── rdoc.js │ │ │ │ ├── rust.js │ │ │ │ ├── sass.js │ │ │ │ ├── scad.js │ │ │ │ ├── scss.js │ │ │ │ ├── text.js │ │ │ │ ├── toml.js │ │ │ │ ├── twig.js │ │ │ │ ├── yaml.js │ │ │ │ ├── cobol.js │ │ │ │ ├── csharp.js │ │ │ │ ├── curly.js │ │ │ │ ├── forth.js │ │ │ │ ├── golang.js │ │ │ │ ├── groovy.js │ │ │ │ ├── jsoniq.js │ │ │ │ ├── julia.js │ │ │ │ ├── latex.js │ │ │ │ ├── liquid.js │ │ │ │ ├── logiql.js │ │ │ │ ├── lucene.js │ │ │ │ ├── matlab.js │ │ │ │ ├── mysql.js │ │ │ │ ├── ocaml.js │ │ │ │ ├── pascal.js │ │ │ │ ├── pgsql.js │ │ │ │ ├── prolog.js │ │ │ │ ├── rhtml.js │ │ │ │ ├── scala.js │ │ │ │ ├── scheme.js │ │ │ │ ├── stylus.js │ │ │ │ ├── xquery.js │ │ │ │ ├── asciidoc.js │ │ │ │ ├── c9search.js │ │ │ │ ├── luapage.js │ │ │ │ ├── mushcode.js │ │ │ │ ├── vbscript.js │ │ │ │ ├── velocity.js │ │ │ │ ├── verilog.js │ │ │ │ ├── batchfile.js │ │ │ │ ├── html_ruby.js │ │ │ │ ├── autohotkey.js │ │ │ │ ├── coldfusion.js │ │ │ │ ├── livescript.js │ │ │ │ ├── objectivec.js │ │ │ │ ├── plain_text.js │ │ │ │ ├── powershell.js │ │ │ │ ├── properties.js │ │ │ │ ├── typescript.js │ │ │ │ ├── assembly_x86.js │ │ │ │ ├── mushcode_high_rules.js │ │ │ │ ├── makefile.js │ │ │ │ ├── snippets.js │ │ │ │ ├── haml.js │ │ │ │ ├── lua.js │ │ │ │ ├── textile.js │ │ │ │ ├── diff.js │ │ │ │ ├── sql.js │ │ │ │ ├── dart.js │ │ │ │ ├── tcl.js │ │ │ │ ├── haskell.js │ │ │ │ ├── markdown.js │ │ │ │ ├── clojure.js │ │ │ │ ├── sh.js │ │ │ │ └── coffee.js │ │ │ │ ├── mode-plain_text.js │ │ │ │ ├── ext-statusbar.js │ │ │ │ ├── ext-themelist.js │ │ │ │ ├── mode-properties.js │ │ │ │ ├── mode-lucene.js │ │ │ │ ├── ext-spellcheck.js │ │ │ │ ├── mode-sql.js │ │ │ │ ├── ext-static_highlight.js │ │ │ │ ├── mode-ada.js │ │ │ │ ├── mode-scheme.js │ │ │ │ ├── mode-lisp.js │ │ │ │ ├── mode-textile.js │ │ │ │ ├── theme-eclipse.js │ │ │ │ ├── theme-xcode.js │ │ │ │ ├── theme-clouds.js │ │ │ │ ├── theme-dawn.js │ │ │ │ ├── mode-cobol.js │ │ │ │ ├── theme-vibrant_ink.js │ │ │ │ ├── ext-whitespace.js │ │ │ │ ├── theme-merbivore.js │ │ │ │ ├── theme-idle_fingers.js │ │ │ │ ├── mode-toml.js │ │ │ │ ├── theme-kr.js │ │ │ │ ├── mode-diff.js │ │ │ │ └── theme-cobalt.js │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── back.png │ │ │ ├── help.png │ │ │ ├── logo.png │ │ │ ├── male.png │ │ │ ├── bullet.png │ │ │ ├── eject.png │ │ │ ├── female.png │ │ │ ├── forward.png │ │ │ ├── lightbulb.png │ │ │ ├── lightning.png │ │ │ ├── information.png │ │ │ └── thymeleaflogonameverysmall.png │ │ ├── jquery │ │ │ └── images │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ ├── ui-icons_2e83ff_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_888888_256x240.png │ │ │ │ ├── ui-icons_cd0a0a_256x240.png │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ ├── WEB-INF │ │ │ ├── appengine-web.xml │ │ │ ├── templates │ │ │ │ ├── exercise03 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise11 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ ├── viewProduct.html │ │ │ │ │ ├── editProduct.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise05 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise21 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise16 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise01 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise02 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise20 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise13 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise04 │ │ │ │ │ ├── question.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise06 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── instructions.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise17 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise10 │ │ │ │ │ ├── instructions.html │ │ │ │ │ ├── question.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise12 │ │ │ │ │ ├── saveCustomer.html │ │ │ │ │ ├── question.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise18 │ │ │ │ │ ├── instructions.html │ │ │ │ │ ├── question.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise08 │ │ │ │ │ ├── instructions.html │ │ │ │ │ ├── question.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise07 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── instructions.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise19 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── instructions.html │ │ │ │ │ └── solution.html │ │ │ │ ├── exercise14 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── exercise15 │ │ │ │ │ ├── question.html │ │ │ │ │ ├── solution.html │ │ │ │ │ └── instructions.html │ │ │ │ ├── about.html │ │ │ │ └── exercise09 │ │ │ │ │ └── question.html │ │ │ └── web.xml │ │ └── js │ │ │ ├── Solution.js │ │ │ ├── Dialog.js │ │ │ ├── Editor.js │ │ │ ├── CodeDialog.js │ │ │ ├── StrokeDetector.js │ │ │ └── ViewUpdater.js │ ├── resources │ │ ├── messages_en.properties │ │ ├── messages_fr.properties │ │ └── messages_es.properties │ └── java │ │ └── org │ │ └── thymeleaf │ │ ├── itutorial │ │ ├── beans │ │ │ ├── Gender.java │ │ │ ├── Amount.java │ │ │ ├── PaymentMethod.java │ │ │ ├── Product.java │ │ │ ├── AmountFormatter.java │ │ │ └── TimestampFormatter.java │ │ ├── EchoController.java │ │ ├── WhitelistTypeLocator.java │ │ ├── IndexController.java │ │ ├── ShowAnswerController.java │ │ ├── ModelAttribute.java │ │ └── ExerciseResourceLoader.java │ │ └── tools │ │ └── memoryexecutor │ │ └── FixedMemoryResourceResolver.java ├── assembly │ └── dist.xml └── test │ └── java │ └── org │ └── thymeleaf │ └── tools │ └── memoryexecutor │ └── StaticTemplateExecutorTest.java ├── .gitignore ├── Procfile ├── DEPLOYING ├── icons_license.txt ├── README.markdown ├── NOTICE.txt └── .gitattributes /system.properties: -------------------------------------------------------------------------------- 1 | java.runtime.version=1.8 2 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-text.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | target/ 4 | bin/ 5 | .settings/ 6 | .idea/ 7 | *.iml 8 | 9 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war 2 | -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /DEPLOYING: -------------------------------------------------------------------------------- 1 | To Heroku: 2 | heroku login 3 | heroku git:remote -a thymeleaf-itutorial 4 | git push heroku 2.1-master:master 5 | -------------------------------------------------------------------------------- /src/main/webapp/images/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/back.png -------------------------------------------------------------------------------- /src/main/webapp/images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/help.png -------------------------------------------------------------------------------- /src/main/webapp/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/logo.png -------------------------------------------------------------------------------- /src/main/webapp/images/male.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/male.png -------------------------------------------------------------------------------- /src/main/webapp/images/bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/bullet.png -------------------------------------------------------------------------------- /src/main/webapp/images/eject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/eject.png -------------------------------------------------------------------------------- /src/main/webapp/images/female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/female.png -------------------------------------------------------------------------------- /src/main/webapp/images/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/forward.png -------------------------------------------------------------------------------- /src/main/webapp/images/lightbulb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/lightbulb.png -------------------------------------------------------------------------------- /src/main/webapp/images/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/lightning.png -------------------------------------------------------------------------------- /src/main/webapp/images/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/information.png -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/d.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/d",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="d"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/ada.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/ada",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="ada"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/dot.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/dot",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="dot"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/ejs.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/ejs",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="ejs"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/ftl.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/ftl",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="ftl"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/ini.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/ini",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="ini"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/jsx.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/jsx",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="jsx"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/svg.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/svg",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="svg"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/xml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/xml",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="xml"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/abap.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/abap",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="abap"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/glsl.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/glsl",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="glsl"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/haxe.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/haxe",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="haxe"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/jade.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/jade",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="jade"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/json.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/json",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="json"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/less.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/less",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="less"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/lisp.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/lisp",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="lisp"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/rdoc.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/rdoc",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="rdoc"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/rust.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/rust",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="rust"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/sass.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/sass",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="sass"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/scad.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/scad",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="scad"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/scss.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/scss",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="scss"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/text.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/text",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="text"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/toml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/toml",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="toml"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/twig.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/twig",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="twig"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/yaml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/yaml",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="yaml"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/cobol.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/cobol",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="cobol"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/csharp.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/csharp",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="csharp"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/curly.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/curly",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="curly"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/forth.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/forth",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="forth"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/golang.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/golang",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="golang"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/groovy.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/groovy",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="groovy"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/jsoniq.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/jsoniq",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="jsoniq"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/julia.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/julia",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="julia"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/latex.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/latex",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="latex"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/liquid.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/liquid",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="liquid"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/logiql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/logiql",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="logiql"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/lucene.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/lucene",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="lucene"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/matlab.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/matlab",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="matlab"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/mysql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/mysql",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="mysql"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/ocaml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/ocaml",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="ocaml"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/pascal.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/pascal",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="pascal"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/pgsql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/pgsql",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="pgsql"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/prolog.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/prolog",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="prolog"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/rhtml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/rhtml",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="rhtml"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/scala.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/scala",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="scala"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/scheme.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/scheme",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="scheme"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/stylus.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/stylus",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="stylus"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/xquery.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/xquery",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="xquery"}) -------------------------------------------------------------------------------- /src/main/webapp/images/thymeleaflogonameverysmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/images/thymeleaflogonameverysmall.png -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/asciidoc.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/asciidoc",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="asciidoc"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/c9search.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/c9search",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="c9search"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/luapage.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/luapage",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="luapage"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/mushcode.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/mushcode",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="mushcode"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/vbscript.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/vbscript",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="vbscript"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/velocity.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/velocity",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="velocity"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/verilog.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/verilog",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="verilog"}) -------------------------------------------------------------------------------- /icons_license.txt: -------------------------------------------------------------------------------- 1 | All icons used in this app, except Thymeleaf logo, are from 2 | http://famfamfam.com/lab/icons/silk/ 3 | with license "Creative Commons Attribution 2.5". 4 | 5 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/batchfile.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/batchfile",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="batchfile"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/html_ruby.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/html_ruby",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="html_ruby"}) -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/autohotkey.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/autohotkey",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="autohotkey"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/coldfusion.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/coldfusion",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="coldfusion"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/livescript.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/livescript",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="livescript"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/objectivec.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/objectivec",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="objectivec"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/plain_text.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/plain_text",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="plain_text"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/powershell.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/powershell",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="powershell"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/properties.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/properties",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="properties"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/typescript.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/typescript",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="typescript"}) -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/assembly_x86.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/assembly_x86",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="assembly_x86"}) -------------------------------------------------------------------------------- /src/main/webapp/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thymeleaf/thymeleaf-itutorial/HEAD/src/main/webapp/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/mushcode_high_rules.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/mushcode_high_rules",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="mushcode_high_rules"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/makefile.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/makefile",["require","exports","module"],function(e,t,n){t.snippetText="snippet ifeq\n ifeq (${1:cond0},${2:cond1})\n ${3:code}\n endif\n",t.scope="makefile"}) -------------------------------------------------------------------------------- /src/main/resources/messages_en.properties: -------------------------------------------------------------------------------- 1 | tutorial.exercise4=Thymeleaf tutorial - exercise 4: internationalization 2 | product.info=Product information 3 | product.name=Product name 4 | product.price=Product price 5 | product.available=Product available from 6 | back=Back 7 | -------------------------------------------------------------------------------- /src/main/resources/messages_fr.properties: -------------------------------------------------------------------------------- 1 | tutorial.exercise4=Tutorial De Thymeleaf - exercice 4: l'internationalisation 2 | product.info=Information du produit 3 | product.name=Nom du produit 4 | product.price=Prix du produit 5 | product.available=Produit disponible depuis 6 | back=Revenir 7 | -------------------------------------------------------------------------------- /src/main/resources/messages_es.properties: -------------------------------------------------------------------------------- 1 | tutorial.exercise4=Tutorial de Thymeleaf - ejercicio 4: internacionalizaci\u00f3n 2 | product.info=Informaci\u00f3n del producto 3 | product.name=Nombre del producto 4 | product.price=Precio del producto 5 | product.available=Producto disponible desde 6 | back=Volver 7 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/snippets.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/snippets",["require","exports","module"],function(e,t,n){t.snippetText="# snippets for making snippets :)\nsnippet snip\n snippet ${1:trigger}\n ${2}\nsnippet msnip\n snippet ${1:trigger} ${2:description}\n ${3}\nsnippet v\n {VISUAL}\n",t.scope="snippets"}) -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/Gender.java: -------------------------------------------------------------------------------- 1 | package org.thymeleaf.itutorial.beans; 2 | 3 | public enum Gender { 4 | 5 | FEMALE("Female gender"), 6 | MALE("Male gender"); 7 | 8 | private String description; 9 | 10 | Gender(final String description) { 11 | this.description = description; 12 | } 13 | 14 | public String getDescription() { 15 | return this.description; 16 | } 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/haml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/haml",["require","exports","module"],function(e,t,n){t.snippetText="snippet t\n %table\n %tr\n %th\n ${1:headers}\n %tr\n %td\n ${2:headers}\nsnippet ul\n %ul\n %li\n ${1:item}\n %li\nsnippet =rp\n = render :partial => '${1:partial}'\nsnippet =rpl\n = render :partial => '${1:partial}', :locals => {}\nsnippet =rpc\n = render :partial => '${1:partial}', :collection => @$1\n\n",t.scope="haml"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/appengine-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | thymeleaf-itutorial 5 | 1 6 | 7 | 8 | 9 | true 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/js/Solution.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Shows the solution to an exercise. 3 | */ 4 | function Solution(CONTEXT_PATH, EXERCISE, EDITOR, callback) { 5 | 6 | this.apply = function() { 7 | var url = CONTEXT_PATH + 'showSolution/' + EXERCISE; 8 | $.ajax({ 9 | url: url, 10 | dataType: 'html', 11 | success : function(code) { 12 | EDITOR.setCode(code); 13 | callback(); 14 | } 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/Amount.java: -------------------------------------------------------------------------------- 1 | package org.thymeleaf.itutorial.beans; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Amount { 6 | 7 | private final BigDecimal amount; 8 | 9 | public Amount(final BigDecimal amount) { 10 | this.amount = amount; 11 | } 12 | 13 | public BigDecimal getAmount() { 14 | return amount; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return amount.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/lua.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/lua",["require","exports","module"],function(e,t,n){t.snippetText="snippet #!\n #!/usr/bin/env lua\n $1\nsnippet local\n local ${1:x} = ${2:1}\nsnippet fun\n function ${1:fname}(${2:...})\n ${3:-- body}\n end\nsnippet for\n for ${1:i}=${2:1},${3:10} do\n ${4:print(i)}\n end\nsnippet forp\n for ${1:i},${2:v} in pairs(${3:table_name}) do\n ${4:-- body}\n end\nsnippet fori\n for ${1:i},${2:v} in ipairs(${3:table_name}) do\n ${4:-- body}\n end\n",t.scope="lua"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-plain_text.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./text_highlight_rules").TextHighlightRules,u=e("./behaviour").Behaviour,a=function(){this.$tokenizer=new s((new o).getRules()),this.$behaviour=new u};r.inherits(a,i),function(){this.getNextLineIndent=function(e,t,n){return""}}.call(a.prototype),t.Mode=a}) -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/PaymentMethod.java: -------------------------------------------------------------------------------- 1 | package org.thymeleaf.itutorial.beans; 2 | 3 | public enum PaymentMethod { 4 | 5 | CREDIT_CARD("Credit card payment"), 6 | DIRECT_DEBIT("Direct debit payment"), 7 | BANK_TRANSFER("Bank transfer payment"); 8 | 9 | private String description; 10 | 11 | PaymentMethod(final String description) { 12 | this.description = description; 13 | } 14 | 15 | public String getDescription() { 16 | return this.description; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/textile.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/textile",["require","exports","module"],function(e,t,n){t.snippetText='# Jekyll post header\nsnippet header\n ---\n title: ${1:title}\n layout: post\n date: ${2:date} ${3:hour:minute:second} -05:00\n ---\n\n# Image\nsnippet img\n !${1:url}(${2:title}):${3:link}!\n\n# Table\nsnippet |\n |${1}|${2}\n\n# Link\nsnippet link\n "${1:link text}":${2:url}\n\n# Acronym\nsnippet (\n (${1:Expand acronym})${2}\n\n# Footnote\nsnippet fn\n [${1:ref number}] ${3}\n\n fn$1. ${2:footnote}\n \n',t.scope="textile"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/diff.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/diff",["require","exports","module"],function(e,t,n){t.snippetText='# DEP-3 (http://dep.debian.net/deps/dep3/) style patch header\nsnippet header DEP-3 style header\n Description: ${1}\n Origin: ${2:vendor|upstream|other}, ${3:url of the original patch}\n Bug: ${4:url in upstream bugtracker}\n Forwarded: ${5:no|not-needed|url}\n Author: ${6:`g:snips_author`}\n Reviewed-by: ${7:name and email}\n Last-Update: ${8:`strftime("%Y-%m-%d")`}\n Applied-Upstream: ${9:upstream version|url|commit}\n\n',t.scope="diff"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise03/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 3 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 3: string concatenation

10 |

Product information

11 |
12 |
Product price
13 |
XXX
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise11/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 11 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 11: links

10 |

Product actions

11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise05/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 5 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 5: escaped and unescaped text

10 |
11 | Some escaped text 12 |
13 |
14 | Some unescaped text 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/js/Dialog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convenience object to manage easily a jQuery-UI Dialect. 3 | */ 4 | function Dialog(elementId) { 5 | 6 | // Initialization 7 | var elementRef = '#' + elementId; 8 | $(elementRef).dialog({ 9 | width: '40%', 10 | height: '400', 11 | dialogClass: 'dialog' 12 | }); 13 | 14 | this.close = function() { 15 | $(elementRef).dialog('close'); 16 | } 17 | 18 | this.toggle = function() { 19 | var isOpen = $(elementRef).dialog('isOpen') 20 | var toggle = isOpen ? 'close' : 'open'; 21 | $(elementRef).dialog(toggle); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | 2 | Thymeleaf Interactive Tutorial Web Application 3 | ============================================== 4 | 5 | ------------------------------------------------------------------------------ 6 | 7 | Project info 8 | ------------ 9 | 10 | This is the source code for the Thymeleaf Interactive Tutorial. 11 | 12 | The Tutorial is a web application hosted at http://itutorial.thymeleaf.org/ 13 | but you also can download the source code and run it in your local java web server. 14 | 15 | 16 | License 17 | ------- 18 | 19 | This software is licensed under the [Apache License 2.0] 20 | (http://www.apache.org/licenses/LICENSE-2.0.html). 21 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise21/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 21 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 21: template uri variables

10 |

Product availability

11 |

12 | There are 5 products in stock. 13 | Buy now! 14 |

15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise05/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 5 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 5: escaped and unescaped text

10 |
11 | Some escaped text 12 |
13 |
14 | Some unescaped text 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise03/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 2 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 3: string concatenation

10 |

Product information

11 |
12 |
Product price
13 |
$350
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | 16 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise16/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 16 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 16: literal substitutions

10 |

Concatenation

11 | Hello, Peter! 12 |

Preprocessing

13 | Hello, Peter! 14 |

Literal substitution

15 | Hello, Peter! 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise11/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 11 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 11: links

10 |

Product actions

11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise21/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 21 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise exercise 21: template uri variables

10 |

Product availability

11 |

12 | There are 5 products in stock. 13 | Buy now! 15 |

16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise01/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 2 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 1: bean values

10 |

Product information

11 |
12 |
Product name
13 |
XXX
14 | 15 |
Product price
16 |
XXX
17 | 18 |
Product available from
19 |
XXX
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise02/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 2 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 2: bean values

10 |

Product information

11 |
12 |
Product name
13 |
XXX
14 | 15 |
Product price
16 |
XXX
17 | 18 |
Product available from
19 |
XXX
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise20/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 20 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 20: conversion service

10 |

Product information

11 |
12 |
Product price:
13 |
$150
14 | 15 |
Product release date:
16 |
23-Jan-2014
17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise20/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 20 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 20: conversion service

10 |

Product information

11 |
12 |
Product price:
13 |
$150
14 | 15 |
Product release date:
16 |
23-Jan-2014
17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise16/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 16 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 16: literal substitutions

10 |

Concatenation

11 | Hello, Peter! 12 |

Preprocessing

13 | Hello, Peter! 14 |

Literal substitution

15 | Hello, Peter! 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise01/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 2 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 1: bean values

10 |

Product information

11 |
12 |
Product name
13 |
Red chair
14 | 15 |
Product price
16 |
350
17 | 18 |
Product available from
19 |
28-Jun-2013
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise02/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 2 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 2: bean values

10 |

Product information

11 |
12 |
Product name
13 |
Red chair
14 | 15 |
Product price
16 |
350
17 | 18 |
Product available from
19 |
28-Jun-2013
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise13/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 13 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 13: inlining

10 |

Birthday email

11 |
12 | 13 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise04/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 4 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 4: internationalization

10 |

Product information

11 |
12 |
Product name
13 |
Red chair
14 | 15 |
Product price
16 |
350
17 | 18 |
Product available from
19 |
28-Jun-2013
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/ext-statusbar.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"],function(e,t,n){var r=e("ace/lib/dom"),i=e("ace/lib/lang"),s=function(e,t){this.element=r.createElement("div"),this.element.className="ace_status-indicator",this.element.style.cssText="display: inline-block;",t.appendChild(this.element);var n=i.delayedCall(function(){this.updateStatus(e)}.bind(this));e.on("changeStatus",function(){n.schedule(100)}),e.on("changeSelection",function(){n.schedule(100)})};(function(){this.updateStatus=function(e){function n(e,n){e&&t.push(e,n||"|")}var t=[];e.$vimModeHandler?n(e.$vimModeHandler.getStatusText()):e.commands.recording&&n("REC");var r=e.selection.lead;n(r.row+":"+r.column," ");if(!e.selection.isEmpty()){var i=e.getSelectionRange();n("("+(i.end.row-i.start.row)+":"+(i.end.column-i.start.column)+")")}t.pop(),this.element.textContent=t.join("")}}).call(s.prototype),t.StatusBar=s}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/sql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/sql",["require","exports","module"],function(e,t,n){t.snippetText="snippet tbl\n create table ${1:table} (\n ${2:columns}\n );\nsnippet col\n ${1:name} ${2:type} ${3:default ''} ${4:not null}\nsnippet ccol\n ${1:name} varchar2(${2:size}) ${3:default ''} ${4:not null}\nsnippet ncol\n ${1:name} number ${3:default 0} ${4:not null}\nsnippet dcol\n ${1:name} date ${3:default sysdate} ${4:not null}\nsnippet ind\n create index ${3:$1_$2} on ${1:table}(${2:column});\nsnippet uind\n create unique index ${1:name} on ${2:table}(${3:column});\nsnippet tblcom\n comment on table ${1:table} is '${2:comment}';\nsnippet colcom\n comment on column ${1:table}.${2:column} is '${3:comment}';\nsnippet addcol\n alter table ${1:table} add (${2:column} ${3:type});\nsnippet seq\n create sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1};\nsnippet s*\n select * from ${1:table}\n",t.scope="sql"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise06/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 6 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 6: iteration

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
DescriptionPriceAvailable from
XXXXXXXXX
27 | 28 | 29 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise11/viewProduct.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 11 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - exercise 11: bean values

10 |

Product information

11 |
12 |
Product name
13 |
Red chair
14 | 15 |
Product price
16 |
350
17 | 18 |
Product available from
19 |
28-Jun-2013
20 |
21 | Back 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise13/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 13 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 13: inlining

10 |

Birthday email

11 |
12 | 13 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/js/Editor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convenience object to manage easily ACE Editor instances. 3 | */ 4 | function Editor(elementId) { 5 | var EDITOR_FONT_SIZE = 14; 6 | var editor; 7 | 8 | init(); 9 | 10 | function init() { 11 | editor = ace.edit(elementId); 12 | editor.getSession().setMode("ace/mode/html"); 13 | editor.setFontSize(EDITOR_FONT_SIZE); 14 | } 15 | 16 | this.setCode = function(code) { 17 | editor.setValue(code); 18 | editor.clearSelection(); 19 | editor.gotoLine(1); 20 | editor.scrollToRow(0); 21 | } 22 | 23 | this.setLanguage = function(language) { 24 | editor.getSession().setMode("ace/mode/" + language); 25 | } 26 | 27 | this.makeReadOnly = function() { 28 | editor.setReadOnly("true"); 29 | } 30 | 31 | this.getCode = function() { 32 | return editor.getValue(); 33 | } 34 | 35 | this.destroy = function() { 36 | editor.destroy(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise17/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 17 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 17: comments

10 | [1] Start of the HTML main content 11 |

Product information

12 |
13 | [2] The bean product is set in the controller 14 |
Product name
15 |
Red chair
16 | 17 |
[3] Product price
18 |
350
19 | 20 |
Product available from
21 |
28-Jun-2013
22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/ext-themelist.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/themelist",["require","exports","module","ace/ext/themelist_utils/themes"],function(e,t,n){n.exports.themes=e("ace/ext/themelist_utils/themes").themes,n.exports.ThemeDescription=function(e){this.name=e,this.desc=e.split("_").map(function(e){return e[0].toUpperCase()+e.slice(1)}).join(" "),this.theme="ace/theme/"+e},n.exports.themesByName={},n.exports.themes=n.exports.themes.map(function(e){return n.exports.themesByName[e]=new n.exports.ThemeDescription(e),n.exports.themesByName[e]})}),ace.define("ace/ext/themelist_utils/themes",["require","exports","module"],function(e,t,n){n.exports.themes=["ambiance","chaos","chrome","clouds","clouds_midnight","cobalt","crimson_editor","dawn","dreamweaver","eclipse","github","idle_fingers","kr_theme","merbivore","merbivore_soft","monokai","mono_industrial","pastel_on_dark","solarized_dark","solarized_light","terminal","textmate","tomorrow","tomorrow_night","tomorrow_night_blue","tomorrow_night_bright","tomorrow_night_eighties","twilight","vibrant_ink","xcode"]}) -------------------------------------------------------------------------------- /src/assembly/dist.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | dist 7 | 8 | 9 | zip 10 | 11 | 12 | 13 | 14 | ${basedir}/target/ 15 | / 16 | 17 | ${project.build.finalName}.war 18 | 19 | 20 | 21 | ${basedir}/ 22 | / 23 | 24 | LICENSE.txt 25 | README.markdown 26 | NOTICE.txt 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-properties.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/properties",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/properties_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./properties_highlight_rules").PropertiesHighlightRules,u=function(){var e=new o;this.$tokenizer=new s(e.getRules())};r.inherits(u,i),t.Mode=u}),ace.define("ace/mode/properties_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=/\\u[0-9a-fA-F]{4}|\\/;this.$rules={start:[{token:"comment",regex:/[!#].*$/},{token:"keyword",regex:/[=:]$/},{token:"keyword",regex:/[=:]/,next:"value"},{token:"constant.language.escape",regex:e},{defaultToken:"variable"}],value:[{regex:/\\$/,token:"string",next:"value"},{regex:/$/,token:"string",next:"start"},{token:"constant.language.escape",regex:e},{defaultToken:"string"}]}};r.inherits(s,i),t.PropertiesHighlightRules=s}) -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.java text diff=java 5 | *.properties text 6 | *.js text 7 | *.css text 8 | *.less text 9 | *.html text diff=html 10 | *.jsp text diff=html 11 | *.jspx text diff=html 12 | *.tag text diff=html 13 | *.tagx text diff=html 14 | *.tld text 15 | *.xml text 16 | *.gradle text 17 | 18 | *.sql text 19 | 20 | *.xsd text 21 | *.dtd text 22 | *.mod text 23 | *.ent text 24 | 25 | *.txt text 26 | *.md text 27 | *.markdown text 28 | 29 | *.thtest text 30 | *.thindex text 31 | *.common text 32 | 33 | *.odt binary 34 | *.pdf binary 35 | 36 | *.sh text eol=lf 37 | *.bat text eol=crlf 38 | 39 | *.ico binary 40 | *.png binary 41 | *.svg binary 42 | *.woff binary 43 | 44 | *.rar binary 45 | *.zargo binary 46 | *.zip binary 47 | 48 | CNAME text 49 | *.MF text 50 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise04/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 4 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 4: internationalization

10 |

Product information

11 |
12 |
Product name
13 |
Red chair
14 | 15 |
Product price
16 |
350
17 | 18 |
Product available from
19 |
28-Jun-2013
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-lucene.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/lucene",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/lucene_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./lucene_highlight_rules").LuceneHighlightRules,u=function(){this.$tokenizer=new s((new o).getRules())};r.inherits(u,i),t.Mode=u}),ace.define("ace/mode/lucene_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{token:"constant.character.negation",regex:"[\\-]"},{token:"constant.character.interro",regex:"[\\?]"},{token:"constant.character.asterisk",regex:"[\\*]"},{token:"constant.character.proximity",regex:"~[0-9]+\\b"},{token:"keyword.operator",regex:"(?:AND|OR|NOT)\\b"},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"keyword",regex:"[\\S]+:"},{token:"string",regex:'".*?"'},{token:"text",regex:"\\s+"}]}};r.inherits(o,s),t.LuceneHighlightRules=o}) -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/Product.java: -------------------------------------------------------------------------------- 1 | package org.thymeleaf.itutorial.beans; 2 | 3 | import java.util.Date; 4 | 5 | public class Product { 6 | 7 | private String description; 8 | private Integer price; 9 | private Date availableFrom; 10 | 11 | public Product(final String description, final Integer price, final Date availableFrom) { 12 | this.description = description; 13 | this.price = price; 14 | this.availableFrom = availableFrom; 15 | } 16 | 17 | public Date getAvailableFrom() { 18 | return this.availableFrom; 19 | } 20 | 21 | public void setAvailableFrom(final Date availableFrom) { 22 | this.availableFrom = availableFrom; 23 | } 24 | 25 | public String getDescription() { 26 | return this.description; 27 | } 28 | 29 | public void setDescription(final String description) { 30 | this.description = description; 31 | } 32 | 33 | public Integer getPrice() { 34 | return this.price; 35 | } 36 | 37 | public void setPrice(final Integer price) { 38 | this.price = price; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise10/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 10: Spring expression language 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | Spring expression language 13 |

14 |
    15 |
  1. 16 | Edit the source code using Spring Expression Language to fill in the four required values. 17 |
  2. 18 |
  3. 19 | You can check the proposed solution by pressing the Show solution button 20 | () above the code editor. 21 |
  4. 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise17/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 17 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 17: comments

10 | 11 |

Product information

12 |
13 | 14 |
Product name
15 |
Red chair
16 | 17 | 21 | 22 |
Product available from
23 |
28-Jun-2013
24 |
25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise10/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 10 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 10: Spring Expression language

10 | 11 |

Arithmetic expressions

12 |

Four multiplied by minus six multiplied by minus two module seven:

13 |

123

14 | 15 |

Object navigation

16 |

Description field of paymentMethod field of the third element of customerList bean:

17 |

Credit card

18 | 19 |

Object instantiation

20 |

Current time milliseconds:

21 |

22-Jun-2013

22 | 23 |

T operator

24 |

Random number:

25 |

123456

26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise12/saveCustomer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 12 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - exercise 12: forms

10 |

Customer information

11 |
12 |
Customer id
13 |
123
14 | 15 |
First name
16 |
John
17 | 18 |
Last name
19 |
Mackenzie
20 | 21 |
Genre
22 |
Male
23 | 24 |
Payment method
25 |
Credit card
26 | 27 |
Balance
28 |
$300
29 |
30 | Back 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise18/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 18: data-* syntax 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces the 11 | HTML5 data-* syntax 13 | from the What's New article.
14 |

15 |
    16 |
  1. 17 | You have the solution of a previous exercise. 18 | Simply substitute the th: syntax by the data- syntax. 19 |
  2. 20 |
  3. 21 | You can check the proposed solution by pressing the Show solution button 22 | () above the code editor. 23 |
  4. 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise08/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 8: conditions 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 7 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to Make the span "Special offer!" appear only 18 | when price is lower than $100. 19 |
  2. 20 |
  3. 21 | You can check the proposed solution by pressing the Show solution button 22 | () above the code editor. 23 |
  4. 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise11/editProduct.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 11 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - exercise 11: bean values

10 |

Product edition

11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | Back 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise07/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 7 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 7: iteration stats

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
IndexDescriptionPriceAvailable from
XXXRed chair$35028-Jun-2013
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise07/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 7: iteration stats 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 6 - section 2 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to show the row index in the first column. 18 | Tip: use the iteration status variable from your th:each. 19 |
  2. 20 |
  3. 21 | You can check the proposed solution by pressing the Show solution button 22 | () above the code editor. 23 |
  4. 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/ext-spellcheck.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"],function(e,t,n){var r=e("../lib/event");t.contextMenuHandler=function(e){var t=e.target,n=t.textInput.getElement();if(!t.selection.isEmpty())return;var i=t.getCursorPosition(),s=t.session.getWordRange(i.row,i.column),o=t.session.getTextRange(s);t.session.tokenRe.lastIndex=0;if(!t.session.tokenRe.test(o))return;var u="",a=o+" "+u;n.value=a,n.setSelectionRange(o.length+1,o.length+1),n.setSelectionRange(0,0);var f=!1;r.addListener(n,"keydown",function l(){r.removeListener(n,"keydown",l),f=!0}),t.textInput.setInputHandler(function(e){console.log(e,a,n.selectionStart,n.selectionEnd);if(e==a)return"";if(e.lastIndexOf(a,0)===0)return e.slice(a.length);if(e.substr(n.selectionEnd)==a)return e.slice(0,-a.length);if(e.slice(-2)==u){var r=e.slice(0,-2);if(r.slice(-1)==" ")return f?r.substring(0,n.selectionEnd):(r=r.slice(0,-1),t.session.replace(s,r),"")}return e})};var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{spellcheck:{set:function(e){var n=this.textInput.getElement();n.spellcheck=!!e,e?this.on("nativecontextmenu",t.contextMenuHandler):this.removeListener("nativecontextmenu",t.contextMenuHandler)},value:!0}})}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise10/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 10 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 10: Spring Expression language

10 | 11 |

Arithmetic expressions

12 |

Four multiplied by minus six multiplied by minus two module seven:

13 |

123

14 | 15 |

Object navigation

16 |

Description field of paymentMethod field of the third element of customerList bean:

17 |

Credit card

18 | 19 |

Object instantiation

20 |

Current time milliseconds:

21 |

22-Jun-2013

22 | 23 |

T operator

24 |

Random number:

25 |

123456

26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise08/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 8 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 8: conditions

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 |
DescriptionPriceAvailable from
Red chair$35028-Jun-2013 26 | Special offer! 27 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise05/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 5: escaped and unescaped text 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 3 - section 2 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | A fragment of HTML code has been set into the context model as a String with variable name html. 18 | You must show it HTML-escaped in the first div and unescaped in the second div. 19 |
  2. 20 |
  3. 21 | You can check the proposed solution by pressing the Show solution button 22 | () above the code editor. 23 |
  4. 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise13/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 13: inlining 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 11 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | There is a String variable with name customerName in the context 18 | model that we want to display instead of the text Peter inside the textarea 19 | element. Substitute it (three times) using Thymeleaf's text inlining. 20 |
  2. 21 |
  3. 22 | You can check the proposed solution by pressing the Show solution button 23 | () above the code editor. 24 |
  4. 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/dart.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/dart",["require","exports","module"],function(e,t,n){t.snippetText='snippet lib\n #library(\'${1}\');\n ${2}\nsnippet im\n #import(\'${1}\');\n ${2}\nsnippet so\n #source(\'${1}\');\n ${2}\nsnippet main\n static void main() {\n ${1:/* code */}\n }\nsnippet st\n static ${1}\nsnippet fi\n final ${1}\nsnippet re\n return ${1}\nsnippet br\n break;\nsnippet th\n throw ${1}\nsnippet cl\n class ${1:`Filename("", "untitled")`} ${2}\nsnippet in\n interface ${1:`Filename("", "untitled")`} ${2}\nsnippet imp\n implements ${1}\nsnippet ext\n extends ${1}\nsnippet if\n if (${1:true}) {\n ${2}\n }\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${3}\n }\nsnippet el\n else\nsnippet sw\n switch (${1}) {\n ${2}\n }\nsnippet cs\n case ${1}:\n ${2}\nsnippet de\n default:\n ${1}\nsnippet for\n for (var ${2:i} = 0, len = ${1:things}.length; $2 < len; ${3:++}$2) {\n ${4:$1[$2]}\n }\nsnippet fore\n for (final ${2:item} in ${1:itemList}) {\n ${3:/* code */}\n }\nsnippet wh\n while (${1:/* condition */}) {\n ${2:/* code */}\n }\nsnippet dowh\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\nsnippet as\n assert(${1:/* condition */});\nsnippet try\n try {\n ${2}\n } catch (${1:Exception e}) {\n }\nsnippet tryf\n try {\n ${2}\n } catch (${1:Exception e}) {\n } finally {\n }\n',t.scope="dart"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise11/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 11: links 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 4 - section 4 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Modify the two links in order to point to /exercise11/product.html URL 18 | with the request parameter action. 19 | The value for action parameter must be view for the first link and 20 | edit for the second. 21 |
  2. 22 |
  3. 23 | You can check the proposed solution by pressing the Show solution button 24 | () above the code editor. 25 |
  4. 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise18/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 18 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 18: data-* syntax

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 |
DescriptionPriceAvailable from
Red chair$35028-Jun-2013 26 | Special offer! 27 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise18/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 18 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 18: data-* syntax

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 |
DescriptionPriceAvailable from
Red chair$35028-Jun-2013 26 | Special offer! 27 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/js/CodeDialog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Show server files (Java, i18n) inside a jQuery-UI Dialog. 3 | */ 4 | // FIXME: reuse dialog 5 | function CodeDialog(CONTEXT_PATH) { 6 | 7 | var DIALOG_ID = 'code-editor'; 8 | var editor, div, url, title, language; 9 | 10 | this.show = function(file) { 11 | if (div) { 12 | clearResources(); 13 | } 14 | parseData(file); 15 | loadCode(); 16 | } 17 | 18 | function parseData(file) { 19 | url = CONTEXT_PATH + 'resources/' + file; 20 | title = file.split('/')[1]; 21 | language = file.split('.')[1]; 22 | } 23 | 24 | function loadCode() { 25 | div = $('
'); 26 | div.attr('id', DIALOG_ID); 27 | $.ajax({ 28 | url: url, 29 | dataType: 'html', 30 | success : showDialog 31 | }); 32 | } 33 | 34 | function showDialog(data) { 35 | $(div).dialog({ 36 | width: '600', 37 | height: '500', 38 | dialogClass: 'dialog', 39 | title: title, 40 | close : clearResources 41 | }); 42 | editor = new Editor(DIALOG_ID); 43 | editor.setLanguage(language); 44 | editor.setCode(data); 45 | editor.makeReadOnly(); 46 | } 47 | 48 | function clearResources() { 49 | editor.destroy(); 50 | div.remove(); 51 | div = null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise06/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 6: iteration 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 6 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to show a list of products as table rows. 18 | A List of objects of class 19 | Product 22 | has been already set into the context model with variable name productList. 23 |
  2. 24 |
  3. 25 | You can check the proposed solution by pressing the Show solution button 26 | () above the code editor. 27 |
  4. 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-sql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/sql_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./sql_highlight_rules").SqlHighlightRules,u=e("../range").Range,a=function(){var e=new o;this.$tokenizer=new s(e.getRules()),this.$keywordList=e.$keywordList};r.inherits(a,i),function(){this.lineCommentStart="--"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/sql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|when|else|end|type|left|right|join|on|outer|desc|asc",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.SqlHighlightRules=s}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise03/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 3: Simple concatenation 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 4 - section 6 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to show product price concatenated –prefixed– with a dollar symbol. 18 | As with previous exercises, a bean of class 19 | Product 22 | has been already set into the context model with variable name product. 23 |
  2. 24 |
  3. 25 | You can check the proposed solution by pressing the Show solution button 26 | () above the code editor. 27 |
  4. 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise21/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 21: template uri variables 5 | 6 | 7 | 8 | 9 |

10 | This exercise shows the syntax for the template URI variables as described in 11 | Link section of the tutorial 13 | (search "variable templates"). 14 |

15 |

16 | This syntax is handy for the construction of REST-style URLs. 17 |

18 |
    19 |
  1. 20 | Two beans, productId and productName have been set into the context. 21 |
  2. 22 |
  3. 23 | Use the path variable syntax to build a URL containing this parameters in the form of: 24 | http://itutorial.thymeleaf.org/buy/273/Red-carpet.html 25 |
  4. 26 |
  5. 27 | You can check the proposed solution by pressing the Show solution button 28 | () above the code editor. 29 |
  6. 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | spring 8 | org.springframework.web.servlet.DispatcherServlet 9 | 1 10 | 11 | 12 | spring 13 | / 14 | 15 | 16 | 17 | encodingFilter 18 | org.springframework.web.filter.CharacterEncodingFilter 19 | 20 | encoding 21 | UTF-8 22 | 23 | 24 | forceEncoding 25 | true 26 | 27 | 28 | 29 | encodingFilter 30 | /* 31 | 32 | 33 | 34 | thymeleafVersion 35 | ${thymeleaf.version} 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/AmountFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The THYMELEAF team. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.thymeleaf.itutorial.beans; 18 | 19 | import java.math.BigDecimal; 20 | import java.text.DecimalFormat; 21 | import java.text.ParseException; 22 | import java.util.Locale; 23 | import org.springframework.format.Formatter; 24 | 25 | public class AmountFormatter implements Formatter { 26 | 27 | private final String pattern = "$ #,##0.00"; 28 | 29 | @Override 30 | public String print(final Amount amount, final Locale locale) { 31 | DecimalFormat df = new DecimalFormat(pattern); 32 | return df.format(amount.getAmount()); 33 | } 34 | 35 | @Override 36 | public Amount parse(final String string, final Locale locale) throws ParseException { 37 | DecimalFormat df = new DecimalFormat(pattern); 38 | BigDecimal amount = new BigDecimal(df.parse(string).doubleValue()); 39 | return new Amount(amount); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/ext-static_highlight.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/static_highlight",["require","exports","module","ace/edit_session","ace/layer/text","ace/config"],function(e,t,n){var r=e("../edit_session").EditSession,i=e("../layer/text").Text,s=".ace_static_highlight {font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace;font-size: 12px;}.ace_static_highlight .ace_gutter {width: 25px !important;display: block;float: left;text-align: right;padding: 0 3px 0 0;margin-right: 3px;position: static !important;}.ace_static_highlight .ace_line { clear: both; }.ace_static_highlight .ace_gutter-cell {-moz-user-select: -moz-none;-khtml-user-select: none;-webkit-user-select: none;user-select: none;}",o=e("../config");t.render=function(e,n,i,s,u,a){function c(){var r=t.renderSync(e,n,i,s,u);return a?a(r):r}var f=0,l=r.prototype.$modes;return typeof i=="string"&&(f++,o.loadModule(["theme",i],function(e){i=e,--f||c()})),typeof n=="string"&&(f++,o.loadModule(["mode",n],function(e){l[n]||(l[n]=new e.Mode),n=l[n],--f||c()})),f||c()},t.renderSync=function(e,t,n,o,u){o=parseInt(o||1,10);var a=new r("");a.setUseWorker(!1),a.setMode(t);var f=new i(document.createElement("div"));f.setSession(a),f.config={characterWidth:10,lineHeight:20},a.setValue(e);var l=[],c=a.getLength();for(var h=0;h"),u||l.push(""+(h+o)+""),f.$renderLine(l,h,!0,!1),l.push("
");var p="
"+"
"+l.join("")+"
"+"
";return f.destroy(),{css:s+n.cssText,html:p}}}) -------------------------------------------------------------------------------- /src/main/webapp/js/StrokeDetector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check for key strokes inside a text editor (maybe a textarea). 3 | * When the user is typing, it does nothing. When the user stop typing for 4 | * a while, executes a function. 5 | * @param String editorId Editor to be checked for key strokes. 6 | * @param Function action Function to be executed when the user stop typing. 7 | */ 8 | function StrokeDetector(editorId, action) { 9 | 10 | var CHECKING_INTERVAL = 1000; // 1 second 11 | var WAIT_FOR_ACTION_INTERVAL = 1000; // 1 second 12 | 13 | var lastStrokeTime, waitingAction; 14 | 15 | init(); 16 | 17 | function init() { 18 | clearStroke(); // Initialize variables 19 | $('#' + editorId).keypress(storeStroke); // Every time a key is pressed store time 20 | setInterval(checkTypingEnd, CHECKING_INTERVAL); // Check if typing has ended regularly 21 | } 22 | 23 | function clearStroke() { 24 | lastStrokeTime = Number.MIN_VALUE; 25 | waitingAction = false; 26 | } 27 | 28 | function storeStroke() { 29 | waitingAction = true; 30 | lastStrokeTime = currentTime(); 31 | } 32 | 33 | function checkTypingEnd() { 34 | if (waitingAction && typingHasEnded()) { 35 | clearStroke(); 36 | action(); 37 | } 38 | } 39 | 40 | function typingHasEnded() { 41 | var now = currentTime(); 42 | var timeSinceLastStroke = now - lastStrokeTime; 43 | return timeSinceLastStroke > WAIT_FOR_ACTION_INTERVAL; 44 | } 45 | } 46 | 47 | function currentTime() { 48 | return new Date().getTime(); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/beans/TimestampFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The THYMELEAF team. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.thymeleaf.itutorial.beans; 18 | 19 | import java.sql.Timestamp; 20 | import java.text.ParseException; 21 | import java.text.SimpleDateFormat; 22 | import java.util.Date; 23 | import java.util.Locale; 24 | import org.springframework.format.Formatter; 25 | 26 | public class TimestampFormatter implements Formatter { 27 | 28 | private final String pattern = "EEEE dd 'of' MMMM, yyyy, 'at' HH:mm"; 29 | 30 | @Override 31 | public String print(final Timestamp time, final Locale locale) { 32 | SimpleDateFormat sdf = new SimpleDateFormat(pattern); 33 | return sdf.format(time); 34 | } 35 | 36 | @Override 37 | public Timestamp parse(final String string, final Locale locale) throws ParseException { 38 | SimpleDateFormat sdf = new SimpleDateFormat(pattern); 39 | Date date = sdf.parse(string); 40 | return new Timestamp(date.getTime()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise19/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 19 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 19: conditional th:remove

10 |

Customer list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
First nameLast nameBalance
PeterJackson350
27 | Mary 28 | 30 | Johanson 31 | 5000
RobertAllen50000
41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/tcl.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/tcl",["require","exports","module"],function(e,t,n){t.snippetText="# #!/usr/bin/env tclsh\nsnippet #!\n #!/usr/bin/env tclsh\n \n# Process\nsnippet pro\n proc ${1:function_name} {${2:args}} {\n ${3:#body ...}\n }\n#xif\nsnippet xif\n ${1:expr}? ${2:true} : ${3:false}\n# Conditional\nsnippet if\n if {${1}} {\n ${2:# body...}\n }\n# Conditional if..else\nsnippet ife\n if {${1}} {\n ${2:# body...}\n } else {\n ${3:# else...}\n }\n# Conditional if..elsif..else\nsnippet ifee\n if {${1}} {\n ${2:# body...}\n } elseif {${3}} {\n ${4:# elsif...}\n } else {\n ${5:# else...}\n }\n# If catch then\nsnippet ifc\n if { [catch {${1:#do something...}} ${2:err}] } {\n ${3:# handle failure...}\n }\n# Catch\nsnippet catch\n catch {${1}} ${2:err} ${3:options}\n# While Loop\nsnippet wh\n while {${1}} {\n ${2:# body...}\n }\n# For Loop\nsnippet for\n for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} {\n ${4:# body...}\n }\n# Foreach Loop\nsnippet fore\n foreach ${1:x} {${2:#list}} {\n ${3:# body...}\n }\n# after ms script...\nsnippet af\n after ${1:ms} ${2:#do something}\n# after cancel id\nsnippet afc\n after cancel ${1:id or script}\n# after idle\nsnippet afi\n after idle ${1:script}\n# after info id\nsnippet afin\n after info ${1:id}\n# Expr\nsnippet exp\n expr {${1:#expression here}}\n# Switch\nsnippet sw\n switch ${1:var} {\n ${3:pattern 1} {\n ${4:#do something}\n }\n default {\n ${2:#do something}\n }\n }\n# Case\nsnippet ca\n ${1:pattern} {\n ${2:#do something}\n }${3}\n# Namespace eval\nsnippet ns\n namespace eval ${1:path} {${2:#script...}}\n# Namespace current\nsnippet nsc\n namespace current\n",t.scope="tcl"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise06/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 6 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 6: iteration

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
DescriptionPriceAvailable from
Red chair$35028-Jun-2013
White table$20015-Jul-2013
Reb table$20015-Jul-2013
Blue table$20015-Jul-2013
42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise20/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 20: conversion service 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces the 11 | Spring Conversion Service integration 13 | from the What's New article.
14 |

15 |
    16 |
  1. 17 | Two beans, releaseDate of type 18 | java.sql.TimeStamp and price of type 19 | Amount 22 | have been set into the context. 23 |
  2. 24 |
  3. 25 | Formatters for these types have also been registered using the Spring Conversion Service. 26 |
  4. 27 |
  5. 28 | Use the new ${{..}} syntax to format these beans using the Conversion Service. 29 |
  6. 30 |
  7. 31 | You can check the proposed solution by pressing the Show solution button 32 | () above the code editor. 33 |
  8. 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise01/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 1: bean values 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 4 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to show bean values instead of that ugly XXX.
    18 | A bean of class 19 | Product 22 | has been already set into the context model with variable name product. 23 |
  2. 24 |
  3. 25 | Now modify the template in order to obtain a static prototype that makes sense (for example, 26 | by substituting all those XXX by some prototyping data). 27 |
  4. 28 |
  5. 29 | You can check the proposed solution by pressing the Show solution button 30 | () above the code editor. 31 |
  6. 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-ada.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/ada",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/ada_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./ada_highlight_rules").AdaHighlightRules,u=e("../range").Range,a=function(){this.$tokenizer=new s((new o).getRules())};r.inherits(a,i),function(){this.lineCommentStart="--"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/ada_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="abort|else|new|return|abs|elsif|not|reverse|abstract|end|null|accept|entry|select|access|exception|of|separate|aliased|exit|or|some|all|others|subtype|and|for|out|synchronized|array|function|overriding|at|tagged|generic|package|task|begin|goto|pragma|terminate|body|private|then|if|procedure|type|case|in|protected|constant|interface|until||is|raise|use|declare|range|delay|limited|record|when|delta|loop|rem|while|digits|renames|with|do|mod|requeue|xor",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce|main",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.AdaHighlightRules=s}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise14/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 14 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 14: same-template fragments

10 |
11 | 15 |
16 |

Product information

17 |
18 |
Product name
19 |
Red chair
20 | 21 |
Product price
22 |
350
23 | 24 |
Product available from
25 |
28-Jun-2013
26 |
27 | 28 |

Customer information

29 |
30 |
First name
31 |
John
32 | 33 |
Last name
34 |
Smith
35 | 36 |
Genre
37 |
Male
38 | 39 |
Payment method
40 |
Credit card
41 | 42 |
Balance
43 |
$350
44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/EchoController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.itutorial; 21 | 22 | import java.io.IOException; 23 | import javax.servlet.http.HttpServletResponse; 24 | import org.springframework.stereotype.Controller; 25 | import org.springframework.web.bind.annotation.RequestMapping; 26 | import org.springframework.web.bind.annotation.RequestMethod; 27 | import org.springframework.web.bind.annotation.RequestParam; 28 | 29 | @Controller 30 | public class EchoController { 31 | 32 | @RequestMapping(value = "/e/c/h/o", method = RequestMethod.POST) // The extra slashes are a trick to allow CSS static prototyping work 33 | public void echo( 34 | @RequestParam("code") final String code, final HttpServletResponse response) throws IOException { 35 | response.setContentType("text/html"); 36 | response.setCharacterEncoding("utf-8"); 37 | response.getWriter().print(code); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/WhitelistTypeLocator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The THYMELEAF team. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.thymeleaf.itutorial; 18 | 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import org.springframework.expression.EvaluationException; 22 | import org.springframework.expression.TypeLocator; 23 | import org.springframework.expression.spel.support.StandardTypeLocator; 24 | 25 | /** 26 | * Decorator for StandardTypeLocator only allowing access to certain fixed types. 27 | */ 28 | public class WhitelistTypeLocator implements TypeLocator { 29 | 30 | private static final List whitelist = Arrays.asList("java.lang.Math", "Math", "java.util.Date"); 31 | 32 | private final StandardTypeLocator standardTypeLocator = new StandardTypeLocator(); 33 | 34 | public WhitelistTypeLocator() { 35 | } 36 | 37 | public Class findType(String typeName) throws EvaluationException { 38 | if (notInWhitelist(typeName)) { 39 | throw new EvaluationException("Forbidden type: " + typeName); 40 | } 41 | return standardTypeLocator.findType(typeName); 42 | } 43 | 44 | private boolean notInWhitelist(String typeName) { 45 | return !whitelist.contains(typeName); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/IndexController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.itutorial; 21 | 22 | import javax.servlet.ServletContext; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.stereotype.Controller; 25 | import org.springframework.ui.Model; 26 | import org.springframework.web.bind.annotation.RequestMapping; 27 | 28 | @Controller 29 | public class IndexController { 30 | 31 | public static final String THYMELEAF_VERSION_PARAMETER = "thymeleafVersion"; 32 | 33 | @Autowired private ServletContext servletContext; 34 | 35 | @RequestMapping("/") 36 | public String index(final Model model) { 37 | model.addAttribute("thymeleafVersion", servletContext.getInitParameter(THYMELEAF_VERSION_PARAMETER)); 38 | model.addAttribute("basicExercises", Exercise.basicExercises()); 39 | model.addAttribute("twoDotOneExercises", Exercise.twoDotOneExercises()); 40 | return "index.html"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-scheme.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/scheme",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/scheme_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./scheme_highlight_rules").SchemeHighlightRules,u=function(){var e=new o;this.$tokenizer=new s(e.getRules())};r.inherits(u,i),function(){this.lineCommentStart=";"}.call(u.prototype),t.Mode=u}),ace.define("ace/mode/scheme_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="case|do|let|loop|if|else|when",t="eq?|eqv?|equal?|and|or|not|null?",n="#t|#f",r="cons|car|cdr|cond|lambda|lambda*|syntax-rules|format|set!|quote|eval|append|list|list?|member?|load",i=this.createKeywordMapper({"keyword.control":e,"keyword.operator":t,"constant.language":n,"support.function":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:";.*$"},{token:["storage.type.function-type.scheme","text","entity.name.function.scheme"],regex:"(?:\\b(?:(define|define-syntax|define-macro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)"},{token:"punctuation.definition.constant.character.scheme",regex:"#:\\S+"},{token:["punctuation.definition.variable.scheme","variable.other.global.scheme","punctuation.definition.variable.scheme"],regex:"(\\*)(\\S*)(\\*)"},{token:"constant.numeric",regex:"#[xXoObB][0-9a-fA-F]+"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?"},{token:i,regex:"[a-zA-Z_#][a-zA-Z0-9_\\-\\?\\!\\*]*"},{token:"string",regex:'"(?=.)',next:"qqstring"}],qqstring:[{token:"constant.character.escape.scheme",regex:"\\\\."},{token:"string",regex:'[^"\\\\]+',merge:!0},{token:"string",regex:"\\\\$",next:"qqstring",merge:!0},{token:"string",regex:'"|$',next:"start",merge:!0}]}};r.inherits(s,i),t.SchemeHighlightRules=s}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise14/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 14 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 14: same-template fragments

10 |
11 | 15 |
16 |

Product information

17 |
18 |
Product name
19 |
Red chair
20 | 21 |
Product price
22 |
350
23 | 24 |
Product available from
25 |
28-Jun-2013
26 |
27 |
Banner
28 |

Customer information

29 |
30 |
First name
31 |
John
32 | 33 |
Last name
34 |
Smith
35 | 36 |
Genre
37 |
Male
38 | 39 |
Payment method
40 |
Credit card
41 | 42 |
Balance
43 |
$350
44 |
45 |
Banner
46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/haskell.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/haskell",["require","exports","module"],function(e,t,n){t.snippetText="snippet lang\n {-# LANGUAGE ${1:OverloadedStrings} #-}\nsnippet info\n -- |\n -- Module : ${1:Module.Namespace}\n -- Copyright : ${2:Author} ${3:2011-2012}\n -- License : ${4:BSD3}\n --\n -- Maintainer : ${5:email@something.com}\n -- Stability : ${6:experimental}\n -- Portability : ${7:unknown}\n --\n -- ${8:Description}\n --\nsnippet import\n import ${1:Data.Text}\nsnippet import2\n import ${1:Data.Text} (${2:head})\nsnippet importq\n import qualified ${1:Data.Text} as ${2:T}\nsnippet inst\n instance ${1:Monoid} ${2:Type} where\n ${3}\nsnippet type\n type ${1:Type} = ${2:Type}\nsnippet data\n data ${1:Type} = ${2:$1} ${3:Int}\nsnippet newtype\n newtype ${1:Type} = ${2:$1} ${3:Int}\nsnippet class\n class ${1:Class} a where\n ${2}\nsnippet module\n module `substitute(substitute(expand('%:r'), '[/\\\\]','.','g'),'^\\%(\\l*\\.\\)\\?','','')` (\n ) where\n `expand('%') =~ 'Main' ? \"\\n\\nmain = do\\n print \\\"hello world\\\"\" : \"\"`\n\nsnippet const\n ${1:name} :: ${2:a}\n $1 = ${3:undefined}\nsnippet fn\n ${1:fn} :: ${2:a} -> ${3:a}\n $1 ${4} = ${5:undefined}\nsnippet fn2\n ${1:fn} :: ${2:a} -> ${3:a} -> ${4:a}\n $1 ${5} = ${6:undefined}\nsnippet ap\n ${1:map} ${2:fn} ${3:list}\nsnippet do\n do\n \nsnippet λ\n \\${1:x} -> ${2}\nsnippet \\\n \\${1:x} -> ${2}\nsnippet <-\n ${1:a} <- ${2:m a}\nsnippet ←\n ${1:a} <- ${2:m a}\nsnippet ->\n ${1:m a} -> ${2:a}\nsnippet →\n ${1:m a} -> ${2:a}\nsnippet tup\n (${1:a}, ${2:b})\nsnippet tup2\n (${1:a}, ${2:b}, ${3:c})\nsnippet tup3\n (${1:a}, ${2:b}, ${3:c}, ${4:d})\nsnippet rec\n ${1:Record} { ${2:recFieldA} = ${3:undefined}\n , ${4:recFieldB} = ${5:undefined}\n }\nsnippet case\n case ${1:something} of\n ${2} -> ${3}\nsnippet let\n let ${1} = ${2}\n in ${3}\nsnippet where\n where\n ${1:fn} = ${2:undefined}\n",t.scope="haskell"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise07/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 7 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 7: iteration stats

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
IndexDescriptionPriceAvailable from
1Red chair$35028-Jun-2013
2White table$20015-Jul-2013
3Reb table$20015-Jul-2013
4Blue table$20015-Jul-2013
47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-lisp.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/lisp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/lisp_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./lisp_highlight_rules").LispHighlightRules,u=function(){var e=new o;this.$tokenizer=new s(e.getRules()),this.$keywordList=e.$keywordList};r.inherits(u,i),function(){this.lineCommentStart=";"}.call(u.prototype),t.Mode=u}),ace.define("ace/mode/lisp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="case|do|let|loop|if|else|when",t="eq|neq|and|or",n="null|nil",r="cons|car|cdr|cond|lambda|format|setq|setf|quote|eval|append|list|listp|memberp|t|load|progn",i=this.createKeywordMapper({"keyword.control":e,"keyword.operator":t,"constant.language":n,"support.function":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:";.*$"},{token:["storage.type.function-type.lisp","text","entity.name.function.lisp"],regex:"(?:\\b(?:(defun|defmethod|defmacro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)"},{token:["punctuation.definition.constant.character.lisp","constant.character.lisp"],regex:"(#)((?:\\w|[\\\\+-=<>'\"&#])+)"},{token:["punctuation.definition.variable.lisp","variable.other.global.lisp","punctuation.definition.variable.lisp"],regex:"(\\*)(\\S*)(\\*)"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"string",regex:'"(?=.)',next:"qqstring"}],qqstring:[{token:"constant.character.escape.lisp",regex:"\\\\."},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"}]}};r.inherits(s,i),t.LispHighlightRules=s}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise15/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 15 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 15: parameterizable fragments

10 |
11 | 15 |
16 |
Banner
17 |

Product information

18 |
19 |
Product name
20 |
Red chair
21 | 22 |
Product price
23 |
350
24 | 25 |
Product available from
26 |
28-Jun-2013
27 |
28 |
Banner
29 |

Customer information

30 |
31 |
First name
32 |
John
33 | 34 |
Last name
35 |
Smith
36 | 37 |
Genre
38 |
Male
39 | 40 |
Payment method
41 |
Credit card
42 | 43 |
Balance
44 |
$350
45 |
46 |
Banner
47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise19/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 19: conditional th:remove 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces the 11 | Conditional th:remove 13 | from the What's New article.
14 |

15 |
    16 |
  1. 17 | You have a context variable called customerList containing a List of 18 | Customer objects. 21 |
  2. 22 |
  3. 23 | The Customer class has a field called personalWebsite which contains the customer 24 | personal website URL, or null if the customer does not have a personal website. 25 |
  4. 26 |
  5. 27 | Use the new conditional th:remove to add a link to the customer personal website 28 | in the displayed first names and last names if the customer has a website. If the customer 29 | does not have a website, simply print their first and last names. 30 |
  6. 31 |
  7. 32 | You can check the proposed solution by pressing the Show solution button 33 | () above the code editor. 34 |
  8. 35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/markdown.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/markdown",["require","exports","module"],function(e,t,n){t.snippetText='# Markdown\n\n# Includes octopress (http://octopress.org/) snippets\n\nsnippet [\n [${1:text}](http://${2:address} "${3:title}")\nsnippet [*\n [${1:link}](${2:`@*`} "${3:title}")${4}\n\nsnippet [:\n [${1:id}]: http://${2:url} "${3:title}"\nsnippet [:*\n [${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ![\n ![${1:alttext}](${2:/images/image.jpg} "${3:title}")\nsnippet ![*\n ![${1:alt}](${2:`@*`} "${3:title}")${4}\n\nsnippet ![:\n ![${1:id}]: ${2:url} "${3:title}"\nsnippet ![:*\n ![${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ===\n `repeat(\'=\', strlen(getline(line(".") - 1)))`\n \n ${1}\nsnippet ---\n `repeat(\'-\', strlen(getline(line(".") - 1)))`\n \n ${1}\n\nsnippet blockquote\n {% blockquote %}\n ${1:quote}\n {% endblockquote %}\n\nsnippet blockquote-author\n {% blockquote ${1:author}, ${2:title} %}\n ${3:quote}\n {% endblockquote %}\n\nsnippet blockquote-link\n {% blockquote ${1:author} ${2:URL} ${3:link_text} %}\n ${4:quote}\n {% endblockquote %}\n\nsnippet bt-codeblock-short\n ```\n ${1:code_snippet}\n ```\n\nsnippet bt-codeblock-full\n ``` ${1:language} ${2:title} ${3:URL} ${4:link_text}\n ${5:code_snippet}\n ```\n\nsnippet codeblock-short\n {% codeblock %}\n ${1:code_snippet}\n {% endcodeblock %}\n\nsnippet codeblock-full\n {% codeblock ${1:title} lang:${2:language} ${3:URL} ${4:link_text} %}\n ${5:code_snippet}\n {% endcodeblock %}\n\nsnippet gist-full\n {% gist ${1:gist_id} ${2:filename} %}\n\nsnippet gist-short\n {% gist ${1:gist_id} %}\n\nsnippet img\n {% img ${1:class} ${2:URL} ${3:width} ${4:height} ${5:title_text} ${6:alt_text} %}\n\nsnippet youtube\n {% youtube ${1:video_id} %}\n\n# The quote should appear only once in the text. It is inherently part of it.\n# See http://octopress.org/docs/plugins/pullquote/ for more info.\n\nsnippet pullquote\n {% pullquote %}\n ${1:text} {" ${2:quote} "} ${3:text}\n {% endpullquote %}\n',t.scope="markdown"}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-textile.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/textile",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/textile_highlight_rules","ace/mode/matching_brace_outdent"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./textile_highlight_rules").TextileHighlightRules,u=e("./matching_brace_outdent").MatchingBraceOutdent,a=function(){this.$tokenizer=new s((new o).getRules()),this.$outdent=new u};r.inherits(a,i),function(){this.getNextLineIndent=function(e,t,n){return e=="intag"?n:""},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)}}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/textile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:function(e){return e.charAt(0)=="h"?"markup.heading."+e.charAt(1):"markup.heading"},regex:"h1|h2|h3|h4|h5|h6|bq|p|bc|pre",next:"blocktag"},{token:"keyword",regex:"[\\*]+|[#]+"},{token:"text",regex:".+"}],blocktag:[{token:"keyword",regex:"\\. ",next:"start"},{token:"keyword",regex:"\\(",next:"blocktagproperties"}],blocktagproperties:[{token:"keyword",regex:"\\)",next:"blocktag"},{token:"string",regex:"[a-zA-Z0-9\\-_]+"},{token:"keyword",regex:"#"}]}};r.inherits(s,i),t.TextileHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/clojure.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/clojure",["require","exports","module"],function(e,t,n){t.snippetText='snippet comm\n (comment\n ${1}\n )\nsnippet condp\n (condp ${1:pred} ${2:expr}\n ${3})\nsnippet def\n (def ${1})\nsnippet defm\n (defmethod ${1:multifn} "${2:doc-string}" ${3:dispatch-val} [${4:args}]\n ${5})\nsnippet defmm\n (defmulti ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defma\n (defmacro ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defn\n (defn ${1:name} "${2:doc-string}" [${3:arg-list}]\n ${4})\nsnippet defp\n (defprotocol ${1:name}\n ${2})\nsnippet defr\n (defrecord ${1:name} [${2:fields}]\n ${3:protocol}\n ${4})\nsnippet deft\n (deftest ${1:name}\n (is (= ${2:assertion})))\n ${3})\nsnippet is\n (is (= ${1} ${2}))\nsnippet defty\n (deftype ${1:Name} [${2:fields}]\n ${3:Protocol}\n ${4})\nsnippet doseq\n (doseq [${1:elem} ${2:coll}]\n ${3})\nsnippet fn\n (fn [${1:arg-list}] ${2})\nsnippet if\n (if ${1:test-expr}\n ${2:then-expr}\n ${3:else-expr})\nsnippet if-let \n (if-let [${1:result} ${2:test-expr}]\n (${3:then-expr} $1)\n (${4:else-expr}))\nsnippet imp\n (:import [${1:package}])\n & {:keys [${1:keys}] :or {${2:defaults}}}\nsnippet let\n (let [${1:name} ${2:expr}]\n ${3})\nsnippet letfn\n (letfn [(${1:name) [${2:args}]\n ${3})])\nsnippet map\n (map ${1:func} ${2:coll})\nsnippet mapl\n (map #(${1:lambda}) ${2:coll})\nsnippet met\n (${1:name} [${2:this} ${3:args}]\n ${4})\nsnippet ns\n (ns ${1:name}\n ${2})\nsnippet dotimes\n (dotimes [_ 10]\n (time\n (dotimes [_ ${1:times}]\n ${2})))\nsnippet pmethod\n (${1:name} [${2:this} ${3:args}])\nsnippet refer\n (:refer-clojure :exclude [${1}])\nsnippet require\n (:require [${1:namespace} :as [${2}]])\nsnippet use\n (:use [${1:namespace} :only [${2}]])\nsnippet print\n (println ${1})\nsnippet reduce\n (reduce ${1:(fn [p n] ${3})} ${2})\nsnippet when\n (when ${1:test} ${2:body})\nsnippet when-let\n (when-let [${1:result} ${2:test}]\n ${3:body})\n',t.scope="clojure"}) -------------------------------------------------------------------------------- /src/main/webapp/js/ViewUpdater.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Manage refreshing of views. 3 | */ 4 | function ViewUpdater(EDITOR, GENERATED_SOURCE, staticViewId, dynamicViewId, CONTEXT_PATH) { 5 | 6 | this.updateAll = function () { 7 | var code = EDITOR.getCode(); 8 | var locale = $('#locale').val(); 9 | showStaticView(code, locale); 10 | showGeneratedSource(code, locale); 11 | showDynamicView(code, locale); 12 | } 13 | 14 | function showStaticView(code, locale) { 15 | postCodeToIframe(code, locale, CONTEXT_PATH + 'e/c/h/o', staticViewId); 16 | } 17 | 18 | function showGeneratedSource(code, locale) { 19 | var url = CONTEXT_PATH + 'generatedSource'; 20 | var data = { 'code' : code, 'locale' : locale } 21 | $.ajax({ 22 | url: url, 23 | type: 'POST', 24 | data: data, 25 | dataType: 'html', 26 | success : setGeneratedSourceCode 27 | }); 28 | } 29 | 30 | function setGeneratedSourceCode(code) { 31 | GENERATED_SOURCE.setCode(code); 32 | } 33 | 34 | function showDynamicView(code, locale) { 35 | postCodeToIframe(code, locale, CONTEXT_PATH + 'dynamicView', dynamicViewId); 36 | } 37 | 38 | function postCodeToIframe(code, locale, url, iframeId) { 39 | var frameName = iframeId; 40 | var frameRef = '#' + iframeId; 41 | var form = $('
', { 42 | action : url, 43 | method : 'post', 44 | target : frameName 45 | }); 46 | var codeInput = $('', { 47 | type : 'hidden', 48 | name : 'code', 49 | value : code 50 | }); 51 | form.append(codeInput); 52 | var localeInput = $('', { 53 | type : 'hidden', 54 | name : 'locale', 55 | value : locale 56 | }); 57 | form.append(localeInput); 58 | form.appendTo(frameRef); 59 | form.submit(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/sh.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/sh",["require","exports","module"],function(e,t,n){t.snippetText='# Shebang. Executing bash via /usr/bin/env makes scripts more portable.\nsnippet #!\n #!/usr/bin/env bash\n \nsnippet if\n if [[ ${1:condition} ]]; then\n ${2:#statements}\n fi\nsnippet elif\n elif [[ ${1:condition} ]]; then\n ${2:#statements}\nsnippet for\n for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do\n ${3:#statements}\n done\nsnippet fori\n for ${1:needle} in ${2:haystack} ; do\n ${3:#statements}\n done\nsnippet wh\n while [[ ${1:condition} ]]; do\n ${2:#statements}\n done\nsnippet until\n until [[ ${1:condition} ]]; do\n ${2:#statements}\n done\nsnippet case\n case ${1:word} in\n ${2:pattern})\n ${3};;\n esac\nsnippet go \n while getopts \'${1:o}\' ${2:opts} \n do \n case $$2 in\n ${3:o0})\n ${4:#staments};;\n esac\n done\n# Set SCRIPT_DIR variable to directory script is located.\nsnippet sdir\n SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"\n# getopt\nsnippet getopt\n __ScriptVersion="${1:version}"\n\n #=== FUNCTION ================================================================\n # NAME: usage\n # DESCRIPTION: Display usage information.\n #===============================================================================\n function usage ()\n {\n cat <<- EOT\n\n Usage : $${0:0} [options] [--] \n\n Options: \n -h|help Display this message\n -v|version Display script version\n\n EOT\n } # ---------- end of function usage ----------\n\n #-----------------------------------------------------------------------\n # Handle command line arguments\n #-----------------------------------------------------------------------\n\n while getopts ":hv" opt\n do\n case $opt in\n\n h|help ) usage; exit 0 ;;\n\n v|version ) echo "$${0:0} -- Version $__ScriptVersion"; exit 0 ;;\n\n \\? ) echo -e "\\n Option does not exist : $OPTARG\\n"\n usage; exit 1 ;;\n\n esac # --- end of case ---\n done\n shift $(($OPTIND-1))\n\n',t.scope="sh"}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise12/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 12 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 12: forms

10 |

Customer edition

11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Genre: 28 | 29 |
30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-eclipse.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/eclipse",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssText='.ace-eclipse .ace_gutter {background: #ebebeb;border-right: 1px solid rgb(159, 159, 159);color: rgb(136, 136, 136);}.ace-eclipse .ace_print-margin {width: 1px;background: #ebebeb;}.ace-eclipse {background-color: #FFFFFF;}.ace-eclipse .ace_fold {background-color: rgb(60, 76, 114);}.ace-eclipse .ace_cursor {border-left: 2px solid black;}.ace-eclipse .ace_storage,.ace-eclipse .ace_keyword,.ace-eclipse .ace_variable {color: rgb(127, 0, 85);}.ace-eclipse .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-eclipse .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-eclipse .ace_function {color: rgb(60, 76, 114);}.ace-eclipse .ace_string {color: rgb(42, 0, 255);}.ace-eclipse .ace_comment {color: rgb(113, 150, 130);}.ace-eclipse .ace_comment.ace_doc {color: rgb(63, 95, 191);}.ace-eclipse .ace_comment.ace_doc.ace_tag {color: rgb(127, 159, 191);}.ace-eclipse .ace_constant.ace_numeric {color: darkblue;}.ace-eclipse .ace_tag {color: rgb(25, 118, 116);}.ace-eclipse .ace_type {color: rgb(127, 0, 127);}.ace-eclipse .ace_xml-pe {color: rgb(104, 104, 91);}.ace-eclipse .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-eclipse .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-eclipse .ace_meta.ace_tag {color:rgb(25, 118, 116);}.ace-eclipse .ace_invisible {color: #ddd;}.ace-eclipse .ace_entity.ace_other.ace_attribute-name {color:rgb(127, 0, 127);}.ace-eclipse .ace_marker-layer .ace_step {background: rgb(255, 255, 0);}.ace-eclipse .ace_marker-layer .ace_active-line {background: rgb(232, 242, 254);}.ace-eclipse .ace_marker-layer .ace_selected-word {border: 1px solid rgb(181, 213, 255);}.ace-eclipse .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.cssClass="ace-eclipse";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise08/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 8 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 8: conditions

10 |

Product list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
DescriptionPriceAvailable from
Red chair$35028-Jun-2013 26 | Special offer! 27 |
White table$20015-Jul-2013
Reb table$15015-Jul-2013Special offer!
Blue table$20015-Jul-2013
49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/ShowAnswerController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.itutorial; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.OutputStream; 25 | import javax.servlet.ServletContext; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.stereotype.Controller; 28 | import org.springframework.util.FileCopyUtils; 29 | import org.springframework.web.bind.annotation.PathVariable; 30 | import org.springframework.web.bind.annotation.RequestMapping; 31 | import org.springframework.web.bind.annotation.RequestMethod; 32 | 33 | @Controller 34 | public class ShowAnswerController { 35 | 36 | @Autowired private ServletContext servletContext; 37 | 38 | @RequestMapping(value = "/showSolution/{index}", method = RequestMethod.GET) 39 | public void showSolution(@PathVariable("index") final Integer index, final OutputStream response) throws IOException { 40 | Exercise exercise = Exercise.get(index); 41 | InputStream template = new ExerciseResourceLoader(servletContext, exercise).getResourceAsStream("solution.html"); 42 | FileCopyUtils.copy(template, response); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise19/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 19 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 19: conditional th:remove

10 |

Customer list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 31 | 32 | 33 | 34 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
First nameLast nameBalance
22 | Peter 25 | 27 | Jackson 30 | 350
35 | Mary 36 | 38 | Johanson 39 | 5000
RobertAllen50000
49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise15/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 15 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 15: parameterizable fragments

10 |
11 | 15 |
16 |
Banner
17 |

Product information

18 |
19 |
Product name
20 |
Red chair
21 | 22 |
Product price
23 |
350
24 | 25 |
Product available from
26 |
28-Jun-2013
27 |
28 |
Banner
29 |

Customer information

30 |
31 |
First name
32 |
John
33 | 34 |
Last name
35 |
Smith
36 | 37 |
Genre
38 |
Male
39 | 40 |
Payment method
41 |
Credit card
42 | 43 |
Balance
44 |
$350
45 |
46 |
Banner
47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-xcode.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/xcode",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-xcode",t.cssText="/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: EE3AD170-2B7F-4DE1-B724-C75F13FE0085) */.ace-xcode .ace_gutter {background: #e8e8e8;color: #333}.ace-xcode .ace_print-margin {width: 1px;background: #e8e8e8}.ace-xcode {background-color: #FFFFFF;color: #000000}.ace-xcode .ace_cursor {border-left: 2px solid #000000}.ace-xcode .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #000000}.ace-xcode .ace_marker-layer .ace_selection {background: #B5D5FF}.ace-xcode.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-xcode .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-xcode .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-xcode .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_gutter-active-line {background-color: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_marker-layer .ace_selected-word {border: 1px solid #B5D5FF}.ace-xcode .ace_constant.ace_language,.ace-xcode .ace_keyword,.ace-xcode .ace_meta,.ace-xcode .ace_variable.ace_language {color: #C800A4}.ace-xcode .ace_invisible {color: #BFBFBF}.ace-xcode .ace_constant.ace_character,.ace-xcode .ace_constant.ace_other {color: #275A5E}.ace-xcode .ace_constant.ace_numeric {color: #3A00DC}.ace-xcode .ace_entity.ace_other.ace_attribute-name,.ace-xcode .ace_support.ace_constant,.ace-xcode .ace_support.ace_function {color: #450084}.ace-xcode .ace_fold {background-color: #C800A4;border-color: #000000}.ace-xcode .ace_entity.ace_name.ace_tag,.ace-xcode .ace_support.ace_class,.ace-xcode .ace_support.ace_type {color: #790EAD}.ace-xcode .ace_storage {color: #C900A4}.ace-xcode .ace_string {color: #DF0002}.ace-xcode .ace_comment {color: #008E00}.ace-xcode .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise17/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 17: comments 5 | 6 | 7 | 8 | 9 |

10 | This exercise features the different types of comments you can use inside 11 | a Thymeleaf template. See the relevant 12 | sections on comments 14 | of the What's New article. 15 |

16 |
    17 |
  1. 18 | You'll see four sections marked with the literals [1], [2], [3] 19 | and [4]. 20 |
  2. 21 |
  3. 22 | HTML comment: we want text [1] to be an HTML comment. This comment will be shown 23 | in both source and generated code. 24 |
  4. 25 |
  5. 26 | Thymeleaf comment: we want text [2] to be a parser-level comment. This comment will 27 | be shown in source code but not in generated HTML. 28 |
  6. 29 |
  7. 30 | Generated-only content: we want section [3] to be shown when the template is executed 31 | but not when it is opened statically. 32 |
  8. 33 |
  9. 34 | Prototype-only content: we want section [4] to be shown when the template is opened 35 | statically but not when it is executed. 36 |
  10. 37 |
  11. 38 | You can check the proposed solution by pressing the Show solution button 39 | () above the code editor. 40 |
  12. 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise12/solution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 12 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Solution for exercise 12: forms

10 |

Customer edition

11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Genre: 21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/ModelAttribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.itutorial; 21 | 22 | public enum ModelAttribute { 23 | 24 | PRODUCT("product", "code/Product.java"), 25 | PRODUCT_LIST("productList", "code/Product.java"), 26 | HTML("html", null), 27 | CUSTOMER_NAME("customerName", null), 28 | CUSTOMER("customer", "code/Customer.java"), 29 | CUSTOMER_LIST("customerList", "code/Customer.java"), 30 | GENDER("(Gender.java)", "code/Gender.java"), 31 | PAYMENT_METHOD("(PaymentMethod.java)", "code/PaymentMethod.java"), 32 | MESSAGES_EN("(messages_en)", "classes/messages_en.properties"), 33 | MESSAGES_ES("(messages_es)", "classes/messages_es.properties"), 34 | MESSAGES_FR("(messages_fr)", "classes/messages_fr.properties"), 35 | AMOUNT("price", "code/Amount.java"), 36 | RELEASE_DATE("releaseDate", null), 37 | PRODUCT_ID("productId", null), 38 | PRODUCT_NAME("productName", null); 39 | 40 | private final String name; 41 | private final String file; 42 | 43 | private ModelAttribute(String name, String file) { 44 | this.name = name; 45 | this.file = file; 46 | } 47 | 48 | public String getName() { 49 | return name; 50 | } 51 | 52 | public String getFile() { 53 | return file; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise14/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 14: same-template fragments 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts new in Thymeleaf 2.1. See 11 | same-template fragments section 13 | of the What's New article. 14 |

15 |
    16 |
  1. 17 | You can see a div with the id bannerElement at the top of the page. 18 | The goal is convert this element into a fragment that will be reused throughout the page. 19 |
  2. 20 |
  3. 21 | First, set /images/logo.png as the source for the img logo element. 22 |
  4. 23 |
  5. 24 | Now, turn the div element into a fragment by using 25 | th:fragment, and include it twice after the Product information section and 26 | after the Customer information section. Comments have been set to help you locate 27 | these places.
    28 | Please include the fragment using two different ways: 29 |
      30 |
    • Firstly, using its fragment name (standard Thymeleaf-to-Thymeleaf) inclusion mechanism.
    • 31 |
    • Secondly, using the DOM selector expression //div[@id='bannerElement'].
    • 32 |
    33 |
  6. 34 |
  7. 35 | You can check the proposed solution by pressing the Show solution button 36 | () above the code editor. 37 |
  8. 38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-clouds.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/clouds",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-clouds",t.cssText='.ace-clouds .ace_gutter {background: #ebebeb;color: #333}.ace-clouds .ace_print-margin {width: 1px;background: #e8e8e8}.ace-clouds {background-color: #FFFFFF;color: #000000}.ace-clouds .ace_cursor {border-left: 2px solid #000000}.ace-clouds .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #000000}.ace-clouds .ace_marker-layer .ace_selection {background: #BDD5FC}.ace-clouds.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-clouds .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-clouds .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-clouds .ace_marker-layer .ace_active-line {background: #FFFBD1}.ace-clouds .ace_gutter-active-line {background-color : #dcdcdc}.ace-clouds .ace_marker-layer .ace_selected-word {border: 1px solid #BDD5FC}.ace-clouds .ace_invisible {color: #BFBFBF}.ace-clouds .ace_keyword,.ace-clouds .ace_meta,.ace-clouds .ace_support.ace_constant.ace_property-value {color: #AF956F}.ace-clouds .ace_keyword.ace_operator {color: #484848}.ace-clouds .ace_keyword.ace_other.ace_unit {color: #96DC5F}.ace-clouds .ace_constant.ace_language {color: #39946A}.ace-clouds .ace_constant.ace_numeric {color: #46A609}.ace-clouds .ace_constant.ace_character.ace_entity {color: #BF78CC}.ace-clouds .ace_invalid {background-color: #FF002A}.ace-clouds .ace_fold {background-color: #AF956F;border-color: #000000}.ace-clouds .ace_storage,.ace-clouds .ace_support.ace_class,.ace-clouds .ace_support.ace_function,.ace-clouds .ace_support.ace_other,.ace-clouds .ace_support.ace_type {color: #C52727}.ace-clouds .ace_string {color: #5D90CD}.ace-clouds .ace_comment {color: #BCC8BA}.ace-clouds .ace_entity.ace_name.ace_tag,.ace-clouds .ace_entity.ace_other.ace_attribute-name {color: #606060}.ace-clouds .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/tools/memoryexecutor/FixedMemoryResourceResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.tools.memoryexecutor; 21 | 22 | import java.io.ByteArrayInputStream; 23 | import java.io.InputStream; 24 | import org.thymeleaf.TemplateProcessingParameters; 25 | import org.thymeleaf.resourceresolver.IResourceResolver; 26 | import org.thymeleaf.util.Validate; 27 | 28 | /** 29 | * This non-standard "resource resolver" always return the template contents provided in the constructor. 30 | * 31 | * It is thought to be use with MemoryTemplateResolver. 32 | */ 33 | class FixedMemoryResourceResolver implements IResourceResolver { 34 | 35 | private static final String NAME = "FixedMemoryResourceResolver"; 36 | 37 | private final String templateContent; 38 | 39 | public FixedMemoryResourceResolver(final String templateContent) { 40 | Validate.notNull(templateContent, "Template content must be non-null"); 41 | this.templateContent = templateContent; 42 | } 43 | 44 | @Override 45 | public String getName() { 46 | return NAME; 47 | } 48 | 49 | @Override 50 | public InputStream getResourceAsStream(final TemplateProcessingParameters tpp, final String templateName) { 51 | return new ByteArrayInputStream(templateContent.getBytes()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/snippets/coffee.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/snippets/coffee",["require","exports","module"],function(e,t,n){t.snippetText="# Closure loop\nsnippet forindo\n for ${1:name} in ${2:array}\n do ($1) ->\n ${3:// body}\n# Array comprehension\nsnippet fora\n for ${1:name} in ${2:array}\n ${3:// body...}\n# Object comprehension\nsnippet foro\n for ${1:key}, ${2:value} of ${3:object}\n ${4:// body...}\n# Range comprehension (inclusive)\nsnippet forr\n for ${1:name} in [${2:start}..${3:finish}]\n ${4:// body...}\nsnippet forrb\n for ${1:name} in [${2:start}..${3:finish}] by ${4:step}\n ${5:// body...}\n# Range comprehension (exclusive)\nsnippet forrex\n for ${1:name} in [${2:start}...${3:finish}]\n ${4:// body...}\nsnippet forrexb\n for ${1:name} in [${2:start}...${3:finish}] by ${4:step}\n ${5:// body...}\n# Function\nsnippet fun\n (${1:args}) ->\n ${2:// body...}\n# Function (bound)\nsnippet bfun\n (${1:args}) =>\n ${2:// body...}\n# Class\nsnippet cla class ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n ${2}\nsnippet cla class .. constructor: ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n constructor: (${2:args}) ->\n ${3}\n\n ${4}\nsnippet cla class .. extends ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n ${3}\nsnippet cla class .. extends .. constructor: ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n constructor: (${3:args}) ->\n ${4}\n\n ${5}\n# If\nsnippet if\n if ${1:condition}\n ${2:// body...}\n# If __ Else\nsnippet ife\n if ${1:condition}\n ${2:// body...}\n else\n ${3:// body...}\n# Else if\nsnippet elif\n else if ${1:condition}\n ${2:// body...}\n# Ternary If\nsnippet ifte\n if ${1:condition} then ${2:value} else ${3:other}\n# Unless\nsnippet unl\n ${1:action} unless ${2:condition}\n# Switch\nsnippet swi\n switch ${1:object}\n when ${2:value}\n ${3:// body...}\n\n# Log\nsnippet log\n console.log ${1}\n# Try __ Catch\nsnippet try\n try\n ${1}\n catch ${2:error}\n ${3}\n# Require\nsnippet req\n ${2:$1} = require '${1:sys}'${3}\n# Export\nsnippet exp\n ${1:root} = exports ? this\n",t.scope="coffee"}) -------------------------------------------------------------------------------- /src/main/java/org/thymeleaf/itutorial/ExerciseResourceLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ============================================================================= 3 | * 4 | * Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * ============================================================================= 19 | */ 20 | package org.thymeleaf.itutorial; 21 | 22 | import java.io.ByteArrayOutputStream; 23 | import java.io.IOException; 24 | import java.io.InputStream; 25 | import javax.servlet.ServletContext; 26 | import org.springframework.util.FileCopyUtils; 27 | 28 | public class ExerciseResourceLoader { 29 | 30 | private static final String TEMPLATE_DIR = "/WEB-INF/templates"; 31 | 32 | private ServletContext context; 33 | private Exercise exercise; 34 | 35 | public ExerciseResourceLoader(final ServletContext context, final Exercise exercise) { 36 | this.context = context; 37 | this.exercise = exercise; 38 | } 39 | 40 | public InputStream getResourceAsStream(final String resource) { 41 | String resourcePath = TEMPLATE_DIR + "/" + exercise.getPath() + "/" + resource; 42 | return context.getResourceAsStream(resourcePath); 43 | } 44 | 45 | public String getResource(final String resource, final String charset) throws IOException { 46 | InputStream resourceStream = getResourceAsStream(resource); 47 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 48 | FileCopyUtils.copy(resourceStream, outputStream); 49 | return outputStream.toString(charset); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise16/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 15: literal substitutions 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces three ways of doing String concatenation in Thymeleaf.
11 | First, 12 | concatenating 14 | from the Using Thymeleaf manual.
15 | Second, 16 | preprocessing 18 | from the Using Thymeleaf manual.
19 | Third, 20 | literal substitutions 22 | from the What's New article. 23 |

24 |
    25 |
  1. 26 | There is a String variable with name customerName in the context 27 | model that we want to display instead of the text Peter inside the three 28 | span elements. 29 |
  2. 30 |
  3. 31 | Substitute it using three diferent syntaxes: 32 |
      33 |
    1. String concatenation
    2. 34 |
    3. Preprocessing
    4. 35 |
    5. Literal substitutions
    6. 36 |
    37 |
  4. 38 |
  5. 39 | You can check the proposed solution by pressing the Show solution button 40 | () above the code editor. 41 |
  6. 42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf Interactive Tutorial 5 | 6 | 7 | 8 | 9 |

10 | Welcome to the Thymeleaf Interactive Tutorial. Thymeleaf version used in this tutorial is 11 | 1.0.0. 12 |

13 |
14 |

15 | This interactive tutorial has been created by the Thymeleaf Team using 16 | The Thymeleaf Template Engine 17 | and other great open source tools like: 18 |

19 | 25 |

26 | The tutorial is gracefully hosted at the 27 | Heroku Cloud Platform 28 |

29 |

30 | Icons used in this app, except Thymeleaf logo, are created by 31 | Mark James 32 |

33 |

34 | You can get the source code of this tutorial at 35 | GitHub. 36 |

37 |

38 | You can find much more documentation on Thymeleaf at the 39 | Thymeleaf website. 40 |

41 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise09/question.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial: exercise 9 5 | 6 | 7 | 8 | 9 |

Thymeleaf tutorial - Answer for exercise 9: more on conditions

10 |

Customer list

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | 35 | 42 | 43 | 44 | 45 | 46 |
First nameLast nameGenderPayment methodBalance
PeterJackson 31 | Male 32 | Female 33 | Unknown 34 | 36 | Direct debit 37 | 38 | 39 | Payment must be done in the next 4 days 40 | 41 | 350
47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-dawn.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/dawn",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-dawn",t.cssText=".ace-dawn .ace_gutter {background: #ebebeb;color: #333}.ace-dawn .ace_print-margin {width: 1px;background: #e8e8e8}.ace-dawn {background-color: #F9F9F9;color: #080808}.ace-dawn .ace_cursor {border-left: 2px solid #000000}.ace-dawn .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #000000}.ace-dawn .ace_marker-layer .ace_selection {background: rgba(39, 95, 255, 0.30)}.ace-dawn.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #F9F9F9;border-radius: 2px}.ace-dawn .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-dawn .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(75, 75, 126, 0.50)}.ace-dawn .ace_marker-layer .ace_active-line {background: rgba(36, 99, 180, 0.12)}.ace-dawn .ace_gutter-active-line {background-color : #dcdcdc}.ace-dawn .ace_marker-layer .ace_selected-word {border: 1px solid rgba(39, 95, 255, 0.30)}.ace-dawn .ace_invisible {color: rgba(75, 75, 126, 0.50)}.ace-dawn .ace_keyword,.ace-dawn .ace_meta {color: #794938}.ace-dawn .ace_constant,.ace-dawn .ace_constant.ace_character,.ace-dawn .ace_constant.ace_character.ace_escape,.ace-dawn .ace_constant.ace_other {color: #811F24}.ace-dawn .ace_invalid.ace_illegal {text-decoration: underline;font-style: italic;color: #F8F8F8;background-color: #B52A1D}.ace-dawn .ace_invalid.ace_deprecated {text-decoration: underline;font-style: italic;color: #B52A1D}.ace-dawn .ace_support {color: #691C97}.ace-dawn .ace_support.ace_constant {color: #B4371F}.ace-dawn .ace_fold {background-color: #794938;border-color: #080808}.ace-dawn .ace_list,.ace-dawn .ace_support.ace_function {color: #693A17}.ace-dawn .ace_storage {font-style: italic;color: #A71D5D}.ace-dawn .ace_string {color: #0B6125}.ace-dawn .ace_string.ace_regexp {color: #CF5628}.ace-dawn .ace_comment {font-style: italic;color: #5A525F}.ace-dawn .ace_variable {color: #234A97}.ace-dawn .ace_heading {color: #19356D}.ace-dawn .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/templates/exercise15/instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thymeleaf tutorial - Exercise 15: parameterizable fragments 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts new in Thymeleaf 2.1. See 11 | parameterizable fragment signatures section 13 | of the What's New article. 14 |

15 |
    16 |
  1. 17 | Let's start with the same-template fragments from the previous exercise. 18 | We have a fragment call banner which is used three times inside the page. 19 | We are going to add two parameters to the fragment so as to change the background color and 20 | the text shown. 21 |
  2. 22 |
  3. 23 | The first parameter will be a CSS class with possible values white, red and 24 | blue. Substitute the provided value white by a fragment parameter. 25 |
  4. 26 |
  5. 27 | The second parameter will be the text shown. 28 | Substitute the provided value The Thymeleaf tutorial by a fragment parameter. 29 |
  6. 30 |
  7. 31 | Now the values for the includes must be: 32 |
      33 |
    1. white and Product information
    2. 34 |
    3. red and Customer information
    4. 35 |
    5. blue and Copyright 2013
    6. 36 |
    37 |
  8. 38 |
  9. 39 | You can check the proposed solution by pressing the Show solution button 40 | () above the code editor. 41 |
  10. 42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-cobol.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/cobol",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/cobol_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./cobol_highlight_rules").CobolHighlightRules,u=e("../range").Range,a=function(){this.$tokenizer=new s((new o).getRules())};r.inherits(a,i),function(){this.lineCommentStart="*"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/cobol_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="ACCEPT|MERGE|SUM|ADD||MESSAGE|TABLE|ADVANCING|MODE|TAPE|AFTER|MULTIPLY|TEST|ALL|NEGATIVE|TEXT|ALPHABET|NEXT|THAN|ALSO|NO|THEN|ALTERNATE|NOT|THROUGH|AND|NUMBER|THRU|ANY|OCCURS|TIME|ARE|OF|TO|AREA|OFF|TOP||ASCENDING|OMITTED|TRUE|ASSIGN|ON|TYPE|AT|OPEN|UNIT|AUTHOR|OR|UNTIL|BEFORE|OTHER|UP|BLANK|OUTPUT|USE|BLOCK|PAGE|USING|BOTTOM|PERFORM|VALUE|BY|PIC|VALUES|CALL|PICTURE|WHEN|CANCEL|PLUS|WITH|CD|POINTER|WRITE|CHARACTER|POSITION||ZERO|CLOSE|POSITIVE|ZEROS|COLUMN|PROCEDURE|ZEROES|COMMA|PROGRAM|COMMON|PROGRAM-ID|COMMUNICATION|QUOTE|COMP|RANDOM|COMPUTE|READ|CONTAINS|RECEIVE|CONFIGURATION|RECORD|CONTINUE|REDEFINES|CONTROL|REFERENCE|COPY|REMAINDER|COUNT|REPLACE|DATA|REPORT|DATE|RESERVE|DAY|RESET|DELETE|RETURN|DESTINATION|REWIND|DISABLE|REWRITE|DISPLAY|RIGHT|DIVIDE|RUN|DOWN|SAME|ELSE|SEARCH|ENABLE|SECTION|END|SELECT|ENVIRONMENT|SENTENCE|EQUAL|SET|ERROR|SIGN|EXIT|SEQUENTIAL|EXTERNAL|SIZE|FLASE|SORT|FILE|SOURCE|LENGTH|SPACE|LESS|STANDARD|LIMIT|START|LINE|STOP|LOCK|STRING|LOW-VALUE|SUBTRACT",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce|main",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"\\*.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.CobolHighlightRules=s}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-vibrant_ink.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/vibrant_ink",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-vibrant-ink",t.cssText=".ace-vibrant-ink .ace_gutter {background: #1a1a1a;color: #BEBEBE}.ace-vibrant-ink .ace_print-margin {width: 1px;background: #1a1a1a}.ace-vibrant-ink {background-color: #0F0F0F;color: #FFFFFF}.ace-vibrant-ink .ace_cursor {border-left: 2px solid #FFFFFF}.ace-vibrant-ink .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #FFFFFF}.ace-vibrant-ink .ace_marker-layer .ace_selection {background: #6699CC}.ace-vibrant-ink.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #0F0F0F;border-radius: 2px}.ace-vibrant-ink .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-vibrant-ink .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-vibrant-ink .ace_marker-layer .ace_active-line {background: #333333}.ace-vibrant-ink .ace_gutter-active-line {background-color: #333333}.ace-vibrant-ink .ace_marker-layer .ace_selected-word {border: 1px solid #6699CC}.ace-vibrant-ink .ace_invisible {color: #404040}.ace-vibrant-ink .ace_keyword,.ace-vibrant-ink .ace_meta {color: #FF6600}.ace-vibrant-ink .ace_constant,.ace-vibrant-ink .ace_constant.ace_character,.ace-vibrant-ink .ace_constant.ace_character.ace_escape,.ace-vibrant-ink .ace_constant.ace_other {color: #339999}.ace-vibrant-ink .ace_constant.ace_numeric {color: #99CC99}.ace-vibrant-ink .ace_invalid,.ace-vibrant-ink .ace_invalid.ace_deprecated {color: #CCFF33;background-color: #000000}.ace-vibrant-ink .ace_fold {background-color: #FFCC00;border-color: #FFFFFF}.ace-vibrant-ink .ace_entity.ace_name.ace_function,.ace-vibrant-ink .ace_support.ace_function,.ace-vibrant-ink .ace_variable {color: #FFCC00}.ace-vibrant-ink .ace_variable.ace_parameter {font-style: italic}.ace-vibrant-ink .ace_string {color: #66FF00}.ace-vibrant-ink .ace_string.ace_regexp {color: #44B4CC}.ace-vibrant-ink .ace_comment {color: #9933CC}.ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name {font-style: italic;color: #99CC99}.ace-vibrant-ink .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYNDTc/oPAALPAZ7hxlbYAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/ext-whitespace.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/whitespace",["require","exports","module","ace/lib/lang"],function(e,t,n){var r=e("../lib/lang");t.$detectIndentation=function(e,t){function h(e){var t=0;for(var r=e;r0&&!(s%c)&&!(l%c)&&(r[c]=(r[c]||0)+1),n[l]=(n[l]||0)+1}s=l;while(a[a.length-1]=="\\")a=e[u++]}var p=r.reduce(function(e,t){return e+t},0),d={score:0,length:0},v=0;for(var u=1;u<12;u++){if(u==1){v=h(u);var m=1}else var m=h(u)/v;r[u]&&(m+=r[u]/p),m>d.score&&(d={score:m,length:u})}if(d.score&&d.score>1.4)var g=d.length;if(i>v+1)return{ch:" ",length:g};if(v+1>i)return{ch:" ",length:g}},t.detectIndentation=function(e){var n=e.getLines(0,1e3),r=t.$detectIndentation(n)||{};return r.ch&&e.setUseSoftTabs(r.ch==" "),r.length&&e.setTabSize(r.length),r},t.trimTrailingSpace=function(e){var t=e.getDocument(),n=t.getAllLines();for(var r=0,i=n.length;r 2 | 3 | 4 | Thymeleaf tutorial - Exercise 2: Simple formatting 5 | 6 | 7 | 8 | 9 |

10 | This exercise introduces concepts from 11 | chapter 16 of the Using Thymeleaf 13 | manual. 14 |

15 |
    16 |
  1. 17 | Edit the source code in order to show bean values as you did in exercise 1.
    18 | A bean of class 19 | Product 22 | has been already set into the context model with variable name product. 23 |
  2. 24 |
  3. 25 | Now let's add some formatting to those Integer and Date properties. For this, 26 | have a look at the definition of the #dates 27 | and #numbers utility objects at the Expression Utility Objects Appendix 28 | of the 29 | Using Thymeleaf 31 | tutorial. 32 |
  4. 33 |
  5. 34 | Finally, modify the template in order to obtain a static prototype that makes sense (for example, 35 | by substituting all those XXX by some prototyping data). 36 |
  6. 37 |
  7. 38 | You can check the proposed solution by pressing the Show solution button 39 | () above the code editor. 40 |
  8. 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-merbivore.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/merbivore",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-merbivore",t.cssText=".ace-merbivore .ace_gutter {background: #202020;color: #E6E1DC}.ace-merbivore .ace_print-margin {width: 1px;background: #555651}.ace-merbivore {background-color: #161616;color: #E6E1DC}.ace-merbivore .ace_cursor {border-left: 2px solid #FFFFFF}.ace-merbivore .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #FFFFFF}.ace-merbivore .ace_marker-layer .ace_selection {background: #454545}.ace-merbivore.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #161616;border-radius: 2px}.ace-merbivore .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-merbivore .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-merbivore .ace_marker-layer .ace_active-line {background: #333435}.ace-merbivore .ace_gutter-active-line {background-color: #333435}.ace-merbivore .ace_marker-layer .ace_selected-word {border: 1px solid #454545}.ace-merbivore .ace_invisible {color: #404040}.ace-merbivore .ace_entity.ace_name.ace_tag,.ace-merbivore .ace_keyword,.ace-merbivore .ace_meta,.ace-merbivore .ace_meta.ace_tag,.ace-merbivore .ace_storage,.ace-merbivore .ace_support.ace_function {color: #FC6F09}.ace-merbivore .ace_constant,.ace-merbivore .ace_constant.ace_character,.ace-merbivore .ace_constant.ace_character.ace_escape,.ace-merbivore .ace_constant.ace_other,.ace-merbivore .ace_support.ace_type {color: #1EDAFB}.ace-merbivore .ace_constant.ace_character.ace_escape {color: #519F50}.ace-merbivore .ace_constant.ace_language {color: #FDC251}.ace-merbivore .ace_constant.ace_library,.ace-merbivore .ace_string,.ace-merbivore .ace_support.ace_constant {color: #8DFF0A}.ace-merbivore .ace_constant.ace_numeric {color: #58C554}.ace-merbivore .ace_invalid {color: #FFFFFF;background-color: #990000}.ace-merbivore .ace_fold {background-color: #FC6F09;border-color: #E6E1DC}.ace-merbivore .ace_comment {font-style: italic;color: #AD2EA4}.ace-merbivore .ace_entity.ace_other.ace_attribute-name {color: #FFFF89}.ace-merbivore .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-idle_fingers.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/idle_fingers",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-idle-fingers",t.cssText=".ace-idle-fingers .ace_gutter {background: #3b3b3b;color: #fff}.ace-idle-fingers .ace_print-margin {width: 1px;background: #3b3b3b}.ace-idle-fingers {background-color: #323232;color: #FFFFFF}.ace-idle-fingers .ace_cursor {border-left: 2px solid #91FF00}.ace-idle-fingers .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #91FF00}.ace-idle-fingers .ace_marker-layer .ace_selection {background: rgba(90, 100, 126, 0.88)}.ace-idle-fingers.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #323232;border-radius: 2px}.ace-idle-fingers .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-idle-fingers .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-idle-fingers .ace_marker-layer .ace_active-line {background: #353637}.ace-idle-fingers .ace_gutter-active-line {background-color: #353637}.ace-idle-fingers .ace_marker-layer .ace_selected-word {border: 1px solid rgba(90, 100, 126, 0.88)}.ace-idle-fingers .ace_invisible {color: #404040}.ace-idle-fingers .ace_keyword,.ace-idle-fingers .ace_meta {color: #CC7833}.ace-idle-fingers .ace_constant,.ace-idle-fingers .ace_constant.ace_character,.ace-idle-fingers .ace_constant.ace_character.ace_escape,.ace-idle-fingers .ace_constant.ace_other,.ace-idle-fingers .ace_support.ace_constant {color: #6C99BB}.ace-idle-fingers .ace_invalid {color: #FFFFFF;background-color: #FF0000}.ace-idle-fingers .ace_fold {background-color: #CC7833;border-color: #FFFFFF}.ace-idle-fingers .ace_support.ace_function {color: #B83426}.ace-idle-fingers .ace_variable.ace_parameter {font-style: italic}.ace-idle-fingers .ace_string {color: #A5C261}.ace-idle-fingers .ace_string.ace_regexp {color: #CCCC33}.ace-idle-fingers .ace_comment {font-style: italic;color: #BC9458}.ace-idle-fingers .ace_meta.ace_tag {color: #FFE5BB}.ace-idle-fingers .ace_entity.ace_name {color: #FFC66D}.ace-idle-fingers .ace_collab.ace_user1 {color: #323232;background-color: #FFF980}.ace-idle-fingers .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjLyZYiPj/8PAAreAwAI1+g0AAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-toml.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/toml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/toml_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./toml_highlight_rules").TomlHighlightRules,u=e("./folding/cstyle").FoldMode,a=function(){var e=new o;this.foldingRules=new u,this.$tokenizer=new s(e.getRules())};r.inherits(a,i),function(){this.lineCommentStart="#"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/toml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=this.createKeywordMapper({"constant.language.boolean":"true|false"},"identifier"),t="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*\\b";this.$rules={start:[{token:"comment.toml",regex:/#.*$/},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:["variable.keygroup.toml"],regex:"(?:^\\s*)(\\[([^\\]]+)\\])"},{token:e,regex:t},{token:"support.date.toml",regex:"\\d{4}-\\d{2}-\\d{2}(T)\\d{2}:\\d{2}:\\d{2}(Z)"},{token:"constant.numeric.toml",regex:"-?\\d+(\\.?\\d+)?"}],qqstring:[{token:"string",regex:"\\\\$",next:"qqstring"},{token:"constant.language.escape",regex:'\\\\[0tnr"\\\\]'},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.TomlHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i){var s=i.index;return i[1]?this.openingBracketBlock(e,i[1],n,s):e.getCommentFoldRange(n,s+i[0].length,1)}if(t!=="markbeginend")return;var i=r.match(this.foldingStopMarker);if(i){var s=i.index+i[0].length;return i[1]?this.closingBracketBlock(e,i[1],n,s):e.getCommentFoldRange(n,s,-1)}}}.call(o.prototype)}) -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/theme-kr.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/kr_theme",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-kr-theme",t.cssText=".ace-kr-theme .ace_gutter {background: #1c1917;color: #FCFFE0}.ace-kr-theme .ace_print-margin {width: 1px;background: #1c1917}.ace-kr-theme {background-color: #0B0A09;color: #FCFFE0}.ace-kr-theme .ace_cursor {border-left: 2px solid #FF9900}.ace-kr-theme .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #FF9900}.ace-kr-theme .ace_marker-layer .ace_selection {background: rgba(170, 0, 255, 0.45)}.ace-kr-theme.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #0B0A09;border-radius: 2px}.ace-kr-theme .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-kr-theme .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 177, 111, 0.32)}.ace-kr-theme .ace_marker-layer .ace_active-line {background: #38403D}.ace-kr-theme .ace_gutter-active-line {background-color : #38403D}.ace-kr-theme .ace_marker-layer .ace_selected-word {border: 1px solid rgba(170, 0, 255, 0.45)}.ace-kr-theme .ace_invisible {color: rgba(255, 177, 111, 0.32)}.ace-kr-theme .ace_keyword,.ace-kr-theme .ace_meta {color: #949C8B}.ace-kr-theme .ace_constant,.ace-kr-theme .ace_constant.ace_character,.ace-kr-theme .ace_constant.ace_character.ace_escape,.ace-kr-theme .ace_constant.ace_other {color: rgba(210, 117, 24, 0.76)}.ace-kr-theme .ace_invalid {color: #F8F8F8;background-color: #A41300}.ace-kr-theme .ace_support {color: #9FC28A}.ace-kr-theme .ace_support.ace_constant {color: #C27E66}.ace-kr-theme .ace_fold {background-color: #949C8B;border-color: #FCFFE0}.ace-kr-theme .ace_support.ace_function {color: #85873A}.ace-kr-theme .ace_storage {color: #FFEE80}.ace-kr-theme .ace_string {color: rgba(164, 161, 181, 0.8)}.ace-kr-theme .ace_string.ace_regexp {color: rgba(125, 255, 192, 0.65)}.ace-kr-theme .ace_comment {font-style: italic;color: #706D5B}.ace-kr-theme .ace_variable {color: #D1A796}.ace-kr-theme .ace_variable.ace_language {color: #FF80E1}.ace-kr-theme .ace_meta.ace_tag {color: #BABD9C}.ace-kr-theme .ace_list {background-color: #0F0040}.ace-kr-theme .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}) -------------------------------------------------------------------------------- /src/test/java/org/thymeleaf/tools/memoryexecutor/StaticTemplateExecutorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The THYMELEAF team. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.thymeleaf.tools.memoryexecutor; 17 | 18 | import org.junit.Test; 19 | import static org.junit.Assert.*; 20 | import org.thymeleaf.context.Context; 21 | import org.thymeleaf.messageresolver.StandardMessageResolver; 22 | import org.thymeleaf.templatemode.StandardTemplateModeHandlers; 23 | 24 | public class StaticTemplateExecutorTest { 25 | 26 | @Test 27 | public void simpleTemplateWithOneVariable() { 28 | String simpleTemplate = 29 | "" 30 | + "" 31 | + " " 32 | + " Test" 33 | + " " 34 | + " " 35 | + "

" 36 | + " " 37 | + ""; 38 | String expected = 39 | "\n" 40 | + "" 41 | + " " 42 | + " Test" 43 | + " " 44 | + " " 45 | + "

Hello world!

" 46 | + " " 47 | + ""; 48 | String templateMode = StandardTemplateModeHandlers.HTML5.getTemplateModeName(); 49 | Context context = new Context(); 50 | context.setVariable("greeting", "Hello world!"); 51 | StandardMessageResolver messageResolver = new StandardMessageResolver(); 52 | StaticTemplateExecutor executor = new StaticTemplateExecutor(context, messageResolver, templateMode); 53 | String result = executor.processTemplateCode(simpleTemplate); 54 | assertEquals(result, expected); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/webapp/ace/src-min-noconflict/mode-diff.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/diff",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/diff_highlight_rules","ace/mode/folding/diff"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./diff_highlight_rules").DiffHighlightRules,u=e("./folding/diff").FoldMode,a=function(){this.$tokenizer=new s((new o).getRules()),this.foldingRules=new u(["diff","index","\\+{3}","@@|\\*{5}"],"i")};r.inherits(a,i),function(){}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/diff_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{regex:"^(?:\\*{15}|={67}|-{3}|\\+{3})$",token:"punctuation.definition.separator.diff",name:"keyword"},{regex:"^(@@)(\\s*.+?\\s*)(@@)(.*)$",token:["constant","constant.numeric","constant","comment.doc.tag"]},{regex:"^(\\d+)([,\\d]+)(a|d|c)(\\d+)([,\\d]+)(.*)$",token:["constant.numeric","punctuation.definition.range.diff","constant.function","constant.numeric","punctuation.definition.range.diff","invalid"],name:"meta."},{regex:"^(\\-{3}|\\+{3}|\\*{3})( .+)$",token:["constant.numeric","meta.tag"]},{regex:"^([!+>])(.*?)(\\s*)$",token:["support.constant","text","invalid"]},{regex:"^([<\\-])(.*?)(\\s*)$",token:["support.function","string","invalid"]},{regex:"^(diff)(\\s+--\\w+)?(.+?)( .+)?$",token:["variable","variable","keyword","variable"]},{regex:"^Index.+$",token:"variable"},{regex:"^\\s+$",token:"text"},{regex:"\\s*$",token:"invalid"},{defaultToken:"invisible",caseInsensitive:!0}]}};r.inherits(s,i),t.DiffHighlightRules=s}),ace.define("ace/mode/folding/diff",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(e,t){this.regExpList=e,this.flag=t,this.foldingStartMarker=RegExp("^("+e.join("|")+")",this.flag)};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i={row:n,column:r.length},o=this.regExpList;for(var u=1;u<=o.length;u++){var a=RegExp("^("+o.slice(0,u).join("|")+")",this.flag);if(a.test(r))break}for(var f=e.getLength();++n