| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent eee8eb8 commit 6b38c71
57 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,10 @@ local.sbt | |||
| 36 | 36 | ||
| 37 | 37 | node_modules | |
| 38 | 38 | ||
| 39 | - common/app/assets/stylesheets/*.min.css | ||
| 39 | + static/compiled | ||
| 40 | + static/hashed | ||
| 41 | + common/conf/assets/assets.map | ||
| 42 | + common/conf/assets/head.min.css | ||
| 40 | 43 | ||
| 41 | 44 | dev/gems | |
| 42 | 45 | dev/casperjs | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,35 +1,34 @@ | |||
| 1 | 1 | Frontend | |
| 2 | 2 | ======== | |
| 3 | - | ||
| 4 | 3 | The Guardian website frontend. | |
| 5 | 4 | ||
| 5 | + | ||
| 6 | 6 | New developers quick-start | |
| 7 | 7 | =========================== | |
| 8 | - | ||
| 9 | 8 | Frontend is a set of Play Framework 2 Scala applications. | |
| 10 | 9 | ||
| 10 | + | ||
| 11 | 11 | Requirements | |
| 12 | 12 | ------------ | |
| 13 | - | ||
| 14 | 13 | * A Mac or Linux pc | |
| 15 | 14 | * Installed Node.js (https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager) | |
| 16 | 15 | * Installed npm (Node package manager - you quite possibly already have this) `sudo apt-get install npm` | |
| 17 | 16 | * Installed GraphicsMagick | |
| 18 | 17 | * Installed Grunt (build tool) `sudo npm -g install grunt-cli` | |
| 19 | - * Installed Ruby >= v1.9.x & [bundler](http://gembundler.com/) (You will already have this installed, but run `ruby -v` to check version number) | ||
| 18 | + * Installed Ruby >= v1.9.x & [bundler](http://gembundler.com/) (You may already have this installed, but run `ruby -v` to check version number) | ||
| 19 | + | ||
| 20 | 20 | ||
| 21 | 21 | NPM ownership | |
| 22 | 22 | ------------- | |
| 23 | - | ||
| 24 | 23 | Sometimes when you install npm it ends up owned by root (but in your home directory). | |
| 25 | 24 | ||
| 26 | 25 | Check that you own your own .npm directory `ls -ld ~/.npm` | |
| 27 | 26 | ||
| 28 | 27 | If it is owned by root then take ownership of it `sudo chown -R username:username ~/.npm` | |
| 29 | 28 | ||
| 29 | + | ||
| 30 | 30 | File handles | |
| 31 | 31 | ------------ | |
| 32 | - | ||
| 33 | 32 | On Linux machines you may run into a "too many files open" error during compilation or reloading. You can find out | |
| 34 | 33 | how many file handles you are allowed per process by running `ulimit -n`. This can be quite low, e.g. 1024 | |
| 35 | 34 | ||
@@ -46,13 +45,13 @@ And in the file `/etc/pam.d/common-session` add the following line. | |||
| 46 | 45 | session required pam_limits.so | |
| 47 | 46 | ``` | |
| 48 | 47 | ||
| 49 | - restart the machine. | ||
| 48 | + Restart the machine. | ||
| 50 | 49 | ||
| 51 | 50 | For more info see http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/ | |
| 52 | 51 | ||
| 52 | + | ||
| 53 | 53 | Configuration | |
| 54 | 54 | ------------- | |
| 55 | - | ||
| 56 | 55 | You'll need a config file called _/etc/gu/install_vars_ with the following content :- | |
| 57 | 56 | ||
| 58 | 57 | ``` | |
@@ -78,30 +77,37 @@ export proxy_host=proxy.somewhere.com | |||
| 78 | 77 | export proxy_port=1234 | |
| 79 | 78 | ``` | |
| 80 | 79 | ||
| 80 | + | ||
| 81 | 81 | Running | |
| 82 | 82 | ------- | |
| 83 | + Assuming you have checked out this project, open a console and change directory | ||
| 84 | + into the root of the project. | ||
| 83 | 85 | ||
| 84 | - Assuming you have checked out this project, open a console and change directory into the root of the project. | ||
| 86 | + Frontend is built in two parts, using Grunt for the client side asset build and | ||
| 87 | + SBT for the Play Framework backend. Neither of these tools are much use for | ||
| 88 | + building the other half of the project and coupling them together with an | ||
| 89 | + integration is one of those bad ideas that is even worse than it sounds. | ||
| 85 | 90 | ||
| 86 | - Start Simple Build Tool (sbt) by running `./sbt012` | ||
| 91 | + Start the Grunt build and watch for development changes: | ||
| 87 | 92 | ||
| 88 | - Once sbt is running (it may take a while first time) then compile the project by typing `compile` (also can take a while first time) | ||
| 89 | - | ||
| 90 | - Switch project by typing `project dev-build` | ||
| 93 | + ``` | ||
| 94 | + ./grunt watch | ||
| 95 | + ``` | ||
| 91 | 96 | ||
| 92 | - Now start the local server by typing `run` (this too will take long the first time) | ||
| 97 | + In another console, start Simple Build Tool (sbt) by running `./sbt`. It may | ||
| 98 | + take a while to start the first time. Once SBT is running, switch project by | ||
| 99 | + typing `project dev-build`. Then compile and run the project locally by typing | ||
| 100 | + `run`. This also can take a while first time. | ||
| 93 | 101 | ||
| 94 | 102 | Now test you are up and running by hitting the following URLs: | |
| 95 | 103 | * http://localhost:9000/books | |
| 96 | 104 | * http://localhost:9000/media/2012/dec/05/newspaper-editors-sign-up-leveson | |
| 97 | 105 | * http://localhost:9000/news/gallery/2012/dec/04/24-hours-in-pictures-gallery | |
| 98 | 106 | ||
| 107 | + Play Framework will recompile code changes on refresh. | ||
| 99 | 108 | ||
| 100 | - To use in Eclipse, use the `eclipsify` command. This will create Eclipse | ||
| 101 | - project and settings files which can be imported using the Import Existing | ||
| 102 | - Project options in Eclipse. | ||
| 103 | - | ||
| 104 | - To use in IntelliJ, see https://github.com/mpeltonen/sbt-idea | ||
| 109 | + To create project files for use in IntelliJ, run the `idea` task from the root | ||
| 110 | + SBT project. see https://github.com/mpeltonen/sbt-idea | ||
| 105 | 111 | ||
| 106 | 112 | Further information on using the Play console is available [here][play2-console]. | |
| 107 | 113 | ||
@@ -113,17 +119,17 @@ typically include: | |||
| 113 | 119 | ||
| 114 | 120 | * `/management`: Operations support as per standard webapp guidelines. See | |
| 115 | 121 | guardian-management. | |
| 116 | - * `/pages/<path>`: Serve the Guardian URL at `<path>` if supported by this | ||
| 122 | + * `/<path>`: Serve the Guardian URL at `<path>` if supported by this | ||
| 117 | 123 | application. | |
| 118 | 124 | * `/assets/<file>`: A convenience for DEV machines. Assets are CDNed in PROD | |
| 119 | 125 | and would not be available on DEV. | |
| 120 | - * `/<path>`: A synonym for `/pages/<path>` as a convenience for DEV machines. | ||
| 121 | 126 | ||
| 122 | 127 | ||
| 123 | 128 | Deploying | |
| 124 | 129 | --------- | |
| 125 | 130 | Deployment uses the [Magenta][magenta] library. | |
| 126 | 131 | ||
| 132 | + | ||
| 127 | 133 | Debugging | |
| 128 | 134 | --------- | |
| 129 | 135 | You can debug your local Frontend application, by attaching a debugger. | |
@@ -136,9 +142,10 @@ Any IDE debugger should be compatible. In IntelliJ, add a new Debug Configuratio | |||
| 136 | 142 | Ensure the Transport is Socket, the Debugger mode is Attach, and the port is set to 1044. | |
| 137 | 143 | Start a new Debug session, and your breakpoints should be active. | |
| 138 | 144 | ||
| 145 | + | ||
| 139 | 146 | Additional Documentation | |
| 140 | 147 | ------------------------ | |
| 141 | - Further documentation notes and useful items can be found in `dev`. | ||
| 148 | + Further documentation notes and useful items can be found in `docs`. | ||
| 142 | 149 | ||
| 143 | 150 | ||
| 144 | 151 | [sbt]: http://www.scala-sbt.org | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,2 +1 @@ | |||
| 1 | - 1000:assets.AssetsPlugin | ||
| 2 | 1 | 1000:com.gu.management.play.InternalManagementPlugin | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,2 @@ | |||
| 1 | 1 | 100:conf.SwitchBoardPlugin | |
| 2 | - | ||
| 3 | - 1000:assets.AssetsPlugin | ||
| 4 | 2 | 1000:com.gu.management.play.InternalManagementPlugin | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,7 +3,7 @@ | |||
| 3 | 3 | # ~~~~ | |
| 4 | 4 | ||
| 5 | 5 | # For dev machines | |
| 6 | - GET /assets/*file controllers.Assets.at(path="/public", file) | ||
| 6 | + GET /assets/*path dev.DevAssetsController.at(path) | ||
| 7 | 7 | ||
| 8 | 8 | # Section paths | |
| 9 | 9 | GET /sections controllers.SectionsController.renderSections() | |
@@ -19,7 +19,7 @@ GET /$path<[\w\d-]*(/[\w\d-]*)?/video/.*>.json controll | |||
| 19 | 19 | GET /$path<[\w\d-]*(/[\w\d-]*)?/video/.*> controllers.VideoController.render(path) | |
| 20 | 20 | ||
| 21 | 21 | # Note: culture|sport|australia are already routed to front. | |
| 22 | - GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>/trails.json controllers.IndexController.renderTrailsJson(path) | ||
| 23 | - GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>/trails controllers.IndexController.renderTrails(path) | ||
| 24 | - GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>.json controllers.IndexController.renderJson(path) | ||
| 25 | - GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?> controllers.IndexController.render(path) | ||
| 22 | + GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>/trails.json controllers.IndexController.renderTrailsJson(path) | ||
| 23 | + GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>/trails controllers.IndexController.renderTrails(path) | ||
| 24 | + GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?>.json controllers.IndexController.renderJson(path) | ||
| 25 | + GET /$path<[\w\d-]*(/[\w\d-]*)?(/[\w\d-]*)?> controllers.IndexController.render(path) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,2 @@ | |||
| 1 | 1 | 100:conf.SwitchBoardPlugin | |
| 2 | - | ||
| 3 | - 1000:assets.AssetsPlugin | ||
| 4 | 2 | 1000:com.gu.management.play.InternalManagementPlugin | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,7 +3,7 @@ | |||
| 3 | 3 | # ~~~~ | |
| 4 | 4 | ||
| 5 | 5 | # For dev machines | |
| 6 | - GET /assets/*file controllers.Assets.at(path="/public", file) | ||
| 6 | + GET /assets/*path dev.DevAssetsController.at(path) | ||
| 7 | 7 | ||
| 8 | 8 | GET /*path.json controllers.ArticleController.renderLatest(path, lastUpdate: Option[String]) | |
| 9 | 9 | GET /*path controllers.ArticleController.renderArticle(path) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,50 @@ | |||
| 1 | + package assets | ||
| 2 | + | ||
| 3 | + import common.Logging | ||
| 4 | + import org.apache.commons.io.IOUtils | ||
| 5 | + import play.api.{ Mode, Play } | ||
| 6 | + import play.api.libs.json.{ JsString, Json, JsObject } | ||
| 7 | + | ||
| 8 | + case class Asset(path: String) { | ||
| 9 | + val asModulePath = path.replace(".js", "") | ||
| 10 | + lazy val md5Key = path.split('.').dropRight(1).last | ||
| 11 | + | ||
| 12 | + override def toString = path | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + class AssetMap(base: String, assetMap: String) { | ||
| 16 | + def apply(path: String): Asset = { | ||
| 17 | + // Reload asset maps on every access in DEV | ||
| 18 | + if (Play.current.mode == Mode.Dev) assets()(path) else memoizedAssets(path) | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + private def assets(): Map[String, Asset] = { | ||
| 22 | + val url = Play.classloader(Play.current).getResource(assetMap) | ||
| 23 | + val json = IOUtils.toString(url) | ||
| 24 | + val js: JsObject = Json.parse(json).asInstanceOf[JsObject] | ||
| 25 | + | ||
| 26 | + val paths = js.fields.toMap mapValues { _.asInstanceOf[JsString].value } | ||
| 27 | + | ||
| 28 | + paths mapValues { path => Asset(base + path) } | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + private lazy val memoizedAssets = assets() | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + class Assets(base: String, assetMap: String = "assets/assets.map") extends Logging { | ||
| 36 | + val lookup = new AssetMap(base, assetMap) | ||
| 37 | + def apply(path: String): Asset = lookup(path) | ||
| 38 | + | ||
| 39 | + object css { | ||
| 40 | + // Reload head css on every access in DEV | ||
| 41 | + def head = if (Play.current.mode == Mode.Dev) css() else memoizedCss | ||
| 42 | + | ||
| 43 | + private def css(): String = { | ||
| 44 | + val url = Play.classloader(Play.current).getResource("assets/head.min.css") | ||
| 45 | + IOUtils.toString(url) | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + private lazy val memoizedCss: String = css() | ||
| 49 | + } | ||
| 50 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments