{"_id":"54b374d273abe90b00106fa5","user":"54a3af95ad78941600ca2e2a","__v":14,"githubsync":"","category":{"_id":"54b35d86aad2810b009507d7","__v":4,"pages":["54b3643373abe90b00106f7a","54b3749ed8ea260b00e4e60f","54b374aed8ea260b00e4e611","54b374d273abe90b00106fa5"],"version":"54b2c93f336cfb0b00608c28","project":"54b2c91287873d1f00dbebdb","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-01-12T05:37:10.271Z","from_sync":false,"order":2,"slug":"static-assets","title":"Static Assets"},"project":"54b2c91287873d1f00dbebdb","version":{"_id":"54b2c93f336cfb0b00608c28","forked_from":"54b2c91287873d1f00dbebde","project":"54b2c91287873d1f00dbebdb","__v":4,"createdAt":"2015-01-11T19:04:31.031Z","releaseDate":"2015-01-11T19:04:31.031Z","categories":["54b2c93f336cfb0b00608c29","54b2cb87db3c741400eac8c2","54b35d86aad2810b009507d7","54b35d91aad2810b009507d8"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"0.4.0","version":"0.4.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-01-12T07:16:34.733Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":2,"body":"Now, the interesting part - wiring it all up.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Manually Wiring it Up\"\n}\n[/block]\nTo manually include an asset in your project, you need to ensure there are sufficient  configuration variables (that will change on an environment by environment basis) in your configuration (assume the service is called app-resource):\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"cdnUrl\\\":\\\"http://localhost:7334/app-resource/\\\",\\n  \\\"bundleVersion\\\":\\\"local\\\"\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nYou should then be able to create a url using the following helper:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function getAssetUrl(config, type, bundle) {\\n  var assetUrl = config.cdnUrl + config.bundleVersion + '/' + type + '/' + bundle + '.' + type;\\n}\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nIf you run locally:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"bosco cdn minify\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\nThe above helper will resolve (for type = 'js' and bundle = 'main') to:\n\n**http://localhost:7334/app-resource/local/js/main.js**  \n\nThis manual mode of operation does not allow you to use bosco cdn in an 'un-minified' mode.  If you do want to use it in unminified mode you need to reference the generated html files instead (as Compoxure does), which can be found via similar URL construction:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"function getAssetHtmlUrl(config, type, bundle) {\\n  var assetUrl = config.cdnUrl + config.bundleVersion + '/html/' + bundle + '.' + type + '.html';\\n}\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\nThe difference is explained in more detail here: [Running a local 'CDN'](doc:running-a-local-cdn).\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Using Bundle Version\"\n}\n[/block]\nBundle Version provides some middleware for Express, and a Hapi plugin, that makes it easier to generate the URL for a static asset using the convention within Bosco.  It assumes that it has been installed within a service or application that has a bosco-service.json file.\n\nYou can add it to your project very simply:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var buildNumber = config.get('build'); // Or whatever appropriate in your environment\\nvar buildVersion = require('bundle-version')(buildNumber, cdnUrl);\\napp.use(buildVersion.middleware);\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nIt takes a few key facts:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Input\",\n    \"h-1\": \"Description\",\n    \"h-2\": \"Example Value\",\n    \"1-0\": \"cdnUrl\",\n    \"1-1\": \"You can manually provide it, or it defaults to checking the header 'x-cdn-url' that is provided by an upstream proxy (e.g. Compoxure).\",\n    \"1-2\": \"http://localhost:7334/ or a cloudfront URL.\",\n    \"2-0\": \"bosco-service.json : service.name\",\n    \"2-1\": \"Name of the service.\",\n    \"2-2\": \"app-resource\",\n    \"0-0\": \"buildNumber\",\n    \"0-1\": \"Current build number - typically written into the application config by the build server.  Default to 'local'.\",\n    \"0-2\": \"local, 105\"\n  },\n  \"cols\": 3,\n  \"rows\": 3\n}\n[/block]\nWhen a request comes in, it uses this information to construct a base CDN url that is applicable to this version of the service, and then re-sets this full URL on the request.\n\nThis means that if you expose the property to your template layer:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var cdnUrl = req.headers['x-cdn-url'];\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nTo your template layer, you can then append a specific bundle or image name to this to generate an actual endpoint that works in both Bosco local cdn as well as on an actual CDN when it is later deployed. e.g.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<img src='{{cdnUrl}}img/image.jpg'/>\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Using Compoxure and Bundle Version\"\n}\n[/block]\nThe final option is to combine Compoxure and Bundle Version together.  In this mode, Bundle Version, and the actual service works in exactly the same way, but you are now able to include the assets in a page processed by Compoxure in a simpler declarative way:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<div cx-bundles=\\\"app-resource/main.css,resource-reviews/main.css,app-resource/main.js\\\" cx-replace-outer=\\\"true\\\" cx-ignore-error=\\\"true\\\"></div>\\n\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\nThis directive is a shortcut to generating a lot of URLs by hand, the end result will be:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\nThis 'magic' works by one simple trick - when you include Bundle Version in a service, it also attaches a header to the response, that tells Compoxure which version of the service is currently running.","excerpt":"","slug":"using-bosco-ified-assets-in-a-service","type":"basic","title":"Referencing assets in templates"}

Referencing assets in templates


Now, the interesting part - wiring it all up. [block:api-header] { "type": "basic", "title": "Manually Wiring it Up" } [/block] To manually include an asset in your project, you need to ensure there are sufficient configuration variables (that will change on an environment by environment basis) in your configuration (assume the service is called app-resource): [block:code] { "codes": [ { "code": "{\n \"cdnUrl\":\"http://localhost:7334/app-resource/\",\n \"bundleVersion\":\"local\"\n}", "language": "json" } ] } [/block] You should then be able to create a url using the following helper: [block:code] { "codes": [ { "code": "function getAssetUrl(config, type, bundle) {\n var assetUrl = config.cdnUrl + config.bundleVersion + '/' + type + '/' + bundle + '.' + type;\n}", "language": "javascript" } ] } [/block] If you run locally: [block:code] { "codes": [ { "code": "bosco cdn minify", "language": "text" } ] } [/block] The above helper will resolve (for type = 'js' and bundle = 'main') to: **http://localhost:7334/app-resource/local/js/main.js** This manual mode of operation does not allow you to use bosco cdn in an 'un-minified' mode. If you do want to use it in unminified mode you need to reference the generated html files instead (as Compoxure does), which can be found via similar URL construction: [block:code] { "codes": [ { "code": "function getAssetHtmlUrl(config, type, bundle) {\n var assetUrl = config.cdnUrl + config.bundleVersion + '/html/' + bundle + '.' + type + '.html';\n}", "language": "text" } ] } [/block] The difference is explained in more detail here: [Running a local 'CDN'](doc:running-a-local-cdn). [block:api-header] { "type": "basic", "title": "Using Bundle Version" } [/block] Bundle Version provides some middleware for Express, and a Hapi plugin, that makes it easier to generate the URL for a static asset using the convention within Bosco. It assumes that it has been installed within a service or application that has a bosco-service.json file. You can add it to your project very simply: [block:code] { "codes": [ { "code": "var buildNumber = config.get('build'); // Or whatever appropriate in your environment\nvar buildVersion = require('bundle-version')(buildNumber, cdnUrl);\napp.use(buildVersion.middleware);", "language": "javascript" } ] } [/block] It takes a few key facts: [block:parameters] { "data": { "h-0": "Input", "h-1": "Description", "h-2": "Example Value", "1-0": "cdnUrl", "1-1": "You can manually provide it, or it defaults to checking the header 'x-cdn-url' that is provided by an upstream proxy (e.g. Compoxure).", "1-2": "http://localhost:7334/ or a cloudfront URL.", "2-0": "bosco-service.json : service.name", "2-1": "Name of the service.", "2-2": "app-resource", "0-0": "buildNumber", "0-1": "Current build number - typically written into the application config by the build server. Default to 'local'.", "0-2": "local, 105" }, "cols": 3, "rows": 3 } [/block] When a request comes in, it uses this information to construct a base CDN url that is applicable to this version of the service, and then re-sets this full URL on the request. This means that if you expose the property to your template layer: [block:code] { "codes": [ { "code": "var cdnUrl = req.headers['x-cdn-url'];", "language": "javascript" } ] } [/block] To your template layer, you can then append a specific bundle or image name to this to generate an actual endpoint that works in both Bosco local cdn as well as on an actual CDN when it is later deployed. e.g. [block:code] { "codes": [ { "code": "<img src='{{cdnUrl}}img/image.jpg'/>", "language": "text" } ] } [/block] [block:api-header] { "type": "basic", "title": "Using Compoxure and Bundle Version" } [/block] The final option is to combine Compoxure and Bundle Version together. In this mode, Bundle Version, and the actual service works in exactly the same way, but you are now able to include the assets in a page processed by Compoxure in a simpler declarative way: [block:code] { "codes": [ { "code": "<div cx-bundles=\"app-resource/main.css,resource-reviews/main.css,app-resource/main.js\" cx-replace-outer=\"true\" cx-ignore-error=\"true\"></div>\n", "language": "html" } ] } [/block] This directive is a shortcut to generating a lot of URLs by hand, the end result will be: [block:code] { "codes": [ { "code": "", "language": "text" } ] } [/block] This 'magic' works by one simple trick - when you include Bundle Version in a service, it also attaches a header to the response, that tells Compoxure which version of the service is currently running.