Last active
December 26, 2015 04:48
-
-
Save beschauer/7095624 to your computer and use it in GitHub Desktop.
Resource Versioning, Cache Busting, Fingerprinting with Playframework 2.1 All resources that are normally located under /assets/xxx now live under /assets/[VERSION]/xxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
�# This is the main configuration file for the application. | |
# ~~~~~ | |
application.version= "1.0.1" | |
# Secret key | |
# ~~~~~ | |
# ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.typesafe.config.ConfigFactory | |
import sbt._ | |
import Keys._ | |
import play.Project._ | |
object ApplicationBuild extends Build { | |
val conf = ConfigFactory.parseFile(new File("conf/application.conf")).resolve() | |
val appVersion = conf.getString("application.version") | |
// ... | |
val main = play.Project(appName, appVersion, appDependencies).settings( | |
// Add your own project settings here | |
testOptions in Test := Nil, | |
requireJs += "app.js", | |
templatesImport += "controllers.TemplateHelper._" // this imports all methods of TemplateHelper in every template file | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@(title: String, loginLevel: Int, appjs: String)(content: Html)<!DOCTYPE html> | |
<!-- =========== Note how you can use TemplateHelpers 'asset' method to include resources. ============ --> | |
<head> | |
<title>MyApp</title> | |
<script type="text/javascript"> | |
window.baseUrl = '@play.api.Play.current.configuration.getString("application.context")'; | |
window.assetBaseUrl = '@assetBaseUrl()'; | |
</script> | |
<link rel="stylesheet" media="screen" href="@asset("stylesheets/bootstrap-2.3.2.min.css")" /> | |
</head> | |
<body> | |
<script src='@asset("jslib/jquery-1.10.1.min.js")'></script> | |
<script src='@asset("jslib/bootstrap-2.3.2.min.js")'></script> | |
@helper.requireJs(core = asset("javascripts/require.js").url, module = asset(appjs).url) | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Map static resources from the /public folder to the /assets URL path | |
GET /assets/:version/*file controllers.VersionedAsset.asset(version, file) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package controllers | |
import play.api.mvc._ | |
import play.api.{Mode, Play} | |
import org.joda.time.DateTime | |
import org.joda.time.format.DateTimeFormat | |
object VersionedAsset extends Controller { | |
val RFC1123_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'").withZoneUTC(); | |
val expiresDate = RFC1123_DATE_TIME_FORMATTER.print(new DateTime().plusYears(1)) | |
val lastModifiedDate = RFC1123_DATE_TIME_FORMATTER.print(new DateTime().minusMonths(3)) | |
val maxAge = "max-age=31536000" // a year in seconds | |
def appVersion = | |
Play.current.configuration.getString("application.version").getOrElse(throw new RuntimeException(s"application.version must be defined in application.conf")) | |
def asset(version: String, file: String) = Action { request => | |
Assets.at(path = "/public", file)(request) match { | |
case result => result.withHeaders( | |
(EXPIRES, expiresDate), | |
(LAST_MODIFIED, lastModifiedDate), | |
(CACHE_CONTROL, maxAge) | |
) | |
} | |
} | |
} | |
object TemplateHelper { | |
def asset(file: String) = controllers.routes.VersionedAsset.asset(VersionedAsset.appVersion, file) | |
def assetBaseUrl() = | |
( | |
play.api.Play.current.configuration.getString("application.context") map ( _ + "/assets/" + VersionedAsset.appVersion ) | |
) getOrElse (throw new RuntimeException(s"application.context must be defined in application.conf")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment