{"id":13995560,"url":"https://github.com/playframework/twirl","last_synced_at":"2025-05-14T04:06:42.179Z","repository":{"id":536128,"uuid":"13022358","full_name":"playframework/twirl","owner":"playframework","description":"Twirl is Play's default template engine","archived":false,"fork":false,"pushed_at":"2025-04-25T13:16:31.000Z","size":2286,"stargazers_count":556,"open_issues_count":36,"forks_count":113,"subscribers_count":37,"default_branch":"main","last_synced_at":"2025-05-05T02:26:13.899Z","etag":null,"topics":["playframework","sbt-plugin","scala","template-engine","template-language","template-library","twirl"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/playframework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["playframework"],"open_collective":"playframework"}},"created_at":"2013-09-22T22:48:40.000Z","updated_at":"2025-04-25T13:14:58.000Z","dependencies_parsed_at":"2023-02-17T03:45:24.174Z","dependency_job_id":"f06a2e2a-55f1-4614-bc55-73b8b18ad32e","html_url":"https://github.com/playframework/twirl","commit_stats":{"total_commits":866,"total_committers":58,"mean_commits":"14.931034482758621","dds":0.8441108545034642,"last_synced_commit":"b0a1f44ef11f157f5222bca5ded6449dcb822272"},"previous_names":[],"tags_count":88,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playframework%2Ftwirl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playframework%2Ftwirl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playframework%2Ftwirl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playframework%2Ftwirl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/playframework","download_url":"https://codeload.github.com/playframework/twirl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254036844,"owners_count":22003654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["playframework","sbt-plugin","scala","template-engine","template-language","template-library","twirl"],"created_at":"2024-08-09T14:03:29.055Z","updated_at":"2025-05-14T04:06:41.514Z","avatar_url":"https://github.com/playframework.png","language":"Scala","readme":"\u003c!--- Copyright (C) from 2022 The Play Framework Contributors \u003chttps://github.com/playframework\u003e, 2011-2021 Lightbend Inc. \u003chttps://www.lightbend.com\u003e --\u003e\n\n# Twirl\n\n[![Twitter Follow](https://img.shields.io/twitter/follow/playframework?label=follow\u0026style=flat\u0026logo=twitter\u0026color=brightgreen)](https://twitter.com/playframework)\n[![Discord](https://img.shields.io/discord/931647755942776882?logo=discord\u0026logoColor=white)](https://discord.gg/g5s2vtZ4Fa)\n[![GitHub Discussions](https://img.shields.io/github/discussions/playframework/playframework?\u0026logo=github\u0026color=brightgreen)](https://github.com/playframework/playframework/discussions)\n[![StackOverflow](https://img.shields.io/static/v1?label=stackoverflow\u0026logo=stackoverflow\u0026logoColor=fe7a16\u0026color=brightgreen\u0026message=playframework)](https://stackoverflow.com/tags/playframework)\n[![YouTube](https://img.shields.io/youtube/channel/views/UCRp6QDm5SDjbIuisUpxV9cg?label=watch\u0026logo=youtube\u0026style=flat\u0026color=brightgreen\u0026logoColor=ff0000)](https://www.youtube.com/channel/UCRp6QDm5SDjbIuisUpxV9cg)\n[![Twitch Status](https://img.shields.io/twitch/status/playframework?logo=twitch\u0026logoColor=white\u0026color=brightgreen\u0026label=live%20stream)](https://www.twitch.tv/playframework)\n[![OpenCollective](https://img.shields.io/opencollective/all/playframework?label=financial%20contributors\u0026logo=open-collective)](https://opencollective.com/playframework)\n\n[![Build Status](https://github.com/playframework/twirl/actions/workflows/build-test.yml/badge.svg)](https://github.com/playframework/twirl/actions/workflows/build-test.yml)\n[![Maven](https://img.shields.io/maven-central/v/org.playframework.twirl/twirl-api_2.13.svg?logo=apache-maven)](https://mvnrepository.com/artifact/org.playframework.twirl/twirl-api_2.13)\n[![Repository size](https://img.shields.io/github/repo-size/playframework/twirl.svg?logo=git)](https://github.com/playframework/twirl)\n[![Scala Steward badge](https://img.shields.io/badge/Scala_Steward-helping-blue.svg?style=flat\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAMAAAARSr4IAAAAVFBMVEUAAACHjojlOy5NWlrKzcYRKjGFjIbp293YycuLa3pYY2LSqql4f3pCUFTgSjNodYRmcXUsPD/NTTbjRS+2jomhgnzNc223cGvZS0HaSD0XLjbaSjElhIr+AAAAAXRSTlMAQObYZgAAAHlJREFUCNdNyosOwyAIhWHAQS1Vt7a77/3fcxxdmv0xwmckutAR1nkm4ggbyEcg/wWmlGLDAA3oL50xi6fk5ffZ3E2E3QfZDCcCN2YtbEWZt+Drc6u6rlqv7Uk0LdKqqr5rk2UCRXOk0vmQKGfc94nOJyQjouF9H/wCc9gECEYfONoAAAAASUVORK5CYII=)](https://scala-steward.org)\n[![Mergify Status](https://img.shields.io/endpoint.svg?url=https://api.mergify.com/v1/badges/playframework/twirl\u0026style=flat)](https://mergify.com)\n\nTwirl is the [Play][play-site] [template engine][docs].\n\nTwirl is automatically available in Play projects and can also be used\nstand-alone without any dependency on Play.\n\nSee the Play [documentation for the template engine][docs] for more information\nabout the template syntax.\n\n## sbt-twirl\n\nTwirl can also be used outside of Play. An sbt plugin is provided for easy\nintegration with Scala or Java projects.\n\n\u003e sbt-twirl requires sbt 1.3.0 or higher.\n\nTo add the sbt plugin to your project add the sbt plugin dependency in\n`project/plugins.sbt`:\n\n```scala\n// twirl 2.0 and newer:\naddSbtPlugin(\"org.playframework.twirl\" % \"sbt-twirl\" % \"LATEST_VERSION\")\n// twirl 1.6:\naddSbtPlugin(\"com.typesafe.play\" % \"sbt-twirl\" % \"1.6.1\")\n// twirl 1.5.1 and before:\naddSbtPlugin(\"com.typesafe.sbt\" % \"sbt-twirl\" % \"1.5.1\")\n```\n\nReplacing the `LATEST_VERSION` with the latest version published, which should be [![Latest version](https://index.scala-lang.org/playframework/twirl/twirl-api/latest.svg?color=orange)](https://index.scala-lang.org/playframework/twirl/twirl-api). And enable the plugin on projects using:\n\n```scala\nsomeProject.enablePlugins(SbtTwirl)\n```\n\nIf you only have a single project and are using a `build.sbt` file, create a\nroot project and enable the twirl plugin like this:\n\n```scala\nlazy val root = (project in file(\".\")).enablePlugins(SbtTwirl)\n```\n\n### Template files\n\nTwirl template files are expected to be placed under `src/main/twirl` or\n`src/test/twirl`, similar to `scala` or `java` sources. The source locations for\ntemplate files can be configured.\n\nTemplate files must be named `{name}.scala.{ext}` where `ext` can be `html`,\n`js`, `xml`, or `txt`.\n\nThe Twirl template compiler is automatically added as a source generator for\nboth the `main`/`compile` and `test` configurations. When you run `compile` or\n`Test/compile` the Twirl compiler will generate Scala source files from the\ntemplates and then these Scala sources will be compiled along with the rest of\nyour project.\n\n### Additional imports\n\nTo add additional imports for the Scala code in template files, use the\n`templateImports` key. For example:\n\n```scala\nTwirlKeys.templateImports += \"org.example._\"\n```\n\n### Source directories\n\nTo configure the source directories where template files will be found, use the\n`compileTemplates / sourceDirectories` key. For example, to have template\nsources alongside Scala or Java source files:\n\n```scala\nCompile / TwirlKeys.compileTemplates / sourceDirectories := (Compile / unmanagedSourceDirectories).value\n```\n\n## maven-twirl\n\nTo use the Twirl plugin in your project add the Maven plugin and\nTwirl API as a dependency into `pom.xml`:\n\n```pom\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.playframework.twirl\u003c/groupId\u003e\n        \u003cartifactId\u003etwirl-api_${SCALA_VERSION}\u003c/artifactId\u003e\n        \u003cversion\u003e${TWIRL_VERSION}\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.playframework.twirl\u003c/groupId\u003e\n            \u003cartifactId\u003etwirl-maven-plugin_${SCALA_VERSION}\u003c/artifactId\u003e\n            \u003cversion\u003e${TWIRL_VERSION}\u003c/version\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003ecompile\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\nReplacing the `TWIRL_VERSION` with the latest version published, which should be [![Latest version](https://index.scala-lang.org/playframework/twirl/twirl-api/latest.svg?color=orange)](https://index.scala-lang.org/playframework/twirl/twirl-api).\n\n### Template files\n\nTwirl template files are expected to be placed under `src/main/twirl` or\n`src/test/twirl`, similar to `scala` or `java` sources. The additional source\nlocations for template files can be configured.\n\nTemplate files must be named `{name}.scala.{ext}` where `ext` can be `html`,\n`js`, `xml`, or `txt`.\n\n### Additional imports\n\nTo add additional imports for the Scala code in template files, use the\n`templateImports` parameter. For example:\n\n```pom\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.playframework.twirl\u003c/groupId\u003e\n    \u003cartifactId\u003etwirl-maven-plugin_${SCALA_VERSION}\u003c/artifactId\u003e\n    \u003cversion\u003e${TWIRL_VERSION}\u003c/version\u003e\n    \u003cconfiguration\u003e\n        \u003ctemplateImports\u003e\n            \u003cimport\u003eorg.example._\u003c/import\u003e\n        \u003c/templateImports\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\n### Source directories\n\nTo configure the source directories where template files will be found, use the\n`sourceDir` parameter. For example:\n\n```pom\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.playframework.twirl\u003c/groupId\u003e\n    \u003cartifactId\u003etwirl-maven-plugin_${SCALA_VERSION}\u003c/artifactId\u003e\n    \u003cversion\u003e${TWIRL_VERSION}\u003c/version\u003e\n    \u003cconfiguration\u003e\n        \u003csourceDir\u003e${project.basedir}/src/main/templates\u003c/sourceDir\u003e\n    \u003c/configuration\u003e\n    \u003cexecutions\u003e\n        \u003cexecution\u003e\n            \u003cid\u003eadditional-source-directory\u003c/id\u003e\n            \u003cgoals\u003e\n                \u003cgoal\u003ecompile\u003c/goal\u003e\n            \u003c/goals\u003e\n            \u003cconfiguration\u003e\n                \u003csourceDir\u003e${project.basedir}/src/main/other-templates\u003c/sourceDir\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n    \u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\n### Scala version\n\nTo configure the Scala version just use the suffix in `artifactId`.\n\n### Other properties\n\nAlso, you can use the next parameters:\n\n```pom\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.playframework.twirl\u003c/groupId\u003e\n    \u003cartifactId\u003etwirl-maven-plugin_${SCALA_VERSION}\u003c/artifactId\u003e\n    \u003cversion\u003e${TWIRL_VERSION}\u003c/version\u003e\n    \u003cconfiguration\u003e\n        \u003cconstructorAnnotations\u003e\n            \u003cannotation\u003e@org.example.MyAnnotation()\u003c/annotation\u003e\n        \u003c/constructorAnnotations\u003e\n        \u003ctemplateFormats\u003e\n            \u003ccsv\u003eplay.twirl.api.TxtFormat\u003c/csv\u003e\n        \u003c/templateFormats\u003e\n        \u003csourceEncoding\u003eUTF-8\u003c/sourceEncoding\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n\n### Snapshots\n\nTo use a snapshot version add the [Sonatype Snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/org/playframework/twirl/) into `pom.xml`:\n\n```pom\n\u003cpluginRepositories\u003e\n    \u003cpluginRepository\u003e\n        \u003cid\u003esonatype-snapshots\u003c/id\u003e\n        \u003curl\u003ehttps://oss.sonatype.org/content/repositories/snapshots/\u003c/url\u003e\n        \u003creleases\u003e\n            \u003cenabled\u003efalse\u003c/enabled\u003e\n        \u003c/releases\u003e\n        \u003csnapshots\u003e\n            \u003cenabled\u003etrue\u003c/enabled\u003e\n        \u003c/snapshots\u003e\n    \u003c/pluginRepository\u003e\n\u003c/pluginRepositories\u003e\n```\n\n## gradle-twirl\n\n⚠️ `org.playframework.twirl` plugin requires Gradle 7.1 or higher.\n\nTo use the Twirl plugin in your project add the gradle plugin and \nTwirl API as a dependency into `build.gradle.kts`:\n\n```kotlin\nplugins {\n  ...\n  id(\"org.playframework.twirl\") version \"LATEST_VERSION\"\n}\n\ndependencies {\n  implementation(\"org.playframework.twirl\", \"twirl-api_${scalaVersion}\", \"LATEST_VERSION\")\n}\n```\n\nReplacing the `LATEST_VERSION` with the latest version published, which should be [![Latest version](https://index.scala-lang.org/playframework/twirl/twirl-api/latest.svg?color=orange)](https://index.scala-lang.org/playframework/twirl/twirl-api).\n\n### Template files\n\nTwirl template files are expected to be placed under `src/main/twirl` or\n`src/test/twirl`, similar to `scala` or `java` sources. The additional source \nlocations for template files can be configured. \n\n⚠️Please note that the output of the template compilation is Scala source code. \nIf you use these templates in your Java source files, you must place them in a _joint compilation_ folder (see the [Gradle Scala Plugin](https://docs.gradle.org/current/userguide/scala_plugin.html#sec:scala_project_layout) documentation for details). \nThe default location for this folder is `src/main/scala`, but it [can be customized](https://stackoverflow.com/questions/23261075/compiling-scala-before-alongside-java-with-gradle).\n\nTemplate files must be named `{name}.scala.{ext}` where `ext` can be `html`,\n`js`, `xml`, or `txt`.\n\n### Additional imports\n\nTo add additional imports for the Scala code in template files, use the\n`templateImports` key. For example:\n\n```kotlin\nsourceSets {\n  main {\n    twirl {\n      templateImports.add(\"org.example._\")\n    }\n  }\n}\n```\n\n### Source directories\n\nTo configure the source directories where template files will be found, use the\n`srcDir` method for [SourceDirectorySet](https://docs.gradle.org/current/javadoc/org/gradle/api/file/SourceDirectorySet.html). For example:\n\n```kotlin\nsourceSets {\n  main {\n    twirl {\n      srcDir(\"app\")\n    }\n  }\n}\n```\n\n### Scala version\n\nTo configure the Scala version use the `scalaVersion` property of [TwirlExtension](gradle-twirl/src/main/java/play/twirl/gradle/TwirlExtension.java) (`2.13` by default).  For example:\n\n```kotlin\ntwirl {\n  scalaVersion.set(\"3\")\n}\n```\n\n### Other properties\n\nAlso, you can use the next properties:\n\n```kotlin\nsourceSets {\n  main {\n    twirl {\n      // Annotations added to constructors in injectable templates\n      constructorAnnotations.add(\"@org.example.MyAnnotation()\")\n      // Defined custom twirl template formats\n      templateFormats.put(\"csv\", \"play.twirl.api.TxtFormat\")\n      // Source encoding for template files and generated scala files\n      sourceEncoding.set(\"\u003cenc\u003e\")\n    }\n  }\n}\n```\n\n### Snapshots\n\nTo use a snapshot version add the [Sonatype Snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/org/playframework/twirl/org.playframework.twirl.gradle.plugin/) into `settings.gradle.kts`:\n\n```kotlin\npluginManagement {\n  repositories {\n    maven {\n      url = uri(\"https://oss.sonatype.org/content/repositories/snapshots\")\n    }\n  }\n}\n```\n\n## Releasing a new version\n\nSee https://github.com/playframework/.github/blob/main/RELEASING.md\n\n## Credits\n\nThe name *twirl* was thought up by the [Spray team][spray] and refers to the\nmagic `@` character in the template language, which is sometimes called \"twirl\".\n\nThe first stand-alone version of Twirl was created by the [Spray team][spray].\n\nAn optimized version of the Twirl parser was contributed by the\n[Scala IDE team][scala-ide].\n\n[play-site]: https://www.playframework.com\n[docs]: https://www.playframework.com/documentation/latest/ScalaTemplates\n[spray]: https://github.com/spray\n[scala-ide]: https://github.com/scala-ide\n","funding_links":["https://github.com/sponsors/playframework","https://opencollective.com/playframework"],"categories":["\u003ca name=\"Scala\"\u003e\u003c/a\u003eScala","Scala","模板引擎","Table of Contents","Templating"],"sub_categories":["Templating","Misc."],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplayframework%2Ftwirl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplayframework%2Ftwirl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplayframework%2Ftwirl/lists"}