{"id":51121908,"url":"https://github.com/ghidinelli/assets.cfc","last_synced_at":"2026-06-25T03:30:50.728Z","repository":{"id":150734743,"uuid":"43722946","full_name":"ghidinelli/assets.cfc","owner":"ghidinelli","description":"Dynamically return a CSS/JS asset from a rev-manifest.json file generated by Gulp/Grunt","archived":false,"fork":false,"pushed_at":"2015-10-06T01:29:32.000Z","size":328,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-04-04T14:13:16.460Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"ColdFusion","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghidinelli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-06T01:01:11.000Z","updated_at":"2023-04-09T03:22:07.967Z","dependencies_parsed_at":"2023-04-09T03:22:07.370Z","dependency_job_id":null,"html_url":"https://github.com/ghidinelli/assets.cfc","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/ghidinelli/assets.cfc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghidinelli%2Fassets.cfc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghidinelli%2Fassets.cfc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghidinelli%2Fassets.cfc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghidinelli%2Fassets.cfc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghidinelli","download_url":"https://codeload.github.com/ghidinelli/assets.cfc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghidinelli%2Fassets.cfc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34758773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-06-25T03:30:50.147Z","updated_at":"2026-06-25T03:30:50.723Z","avatar_url":"https://github.com/ghidinelli.png","language":"ColdFusion","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Assets.cfc\nDynamically return a CSS/JS asset from a JSON manifest file for management of cachebusted filenames as generated by Gulp/Grunt build pipelines in ColdFusion applications.\n\n# What does this do?\nIn modern web apps, we concatenate and minify our CSS and JS to improve the performance of our applications. For performance we enable long-lived caching headers to minimize repeat downloads. This requires us to change the filename each time we modify an asset (or else 'styles.css' won't be re-downloaded and the user won't see our changes if they've previously visited our site).  \n\nWe use Gulp, an awesome Javascript-based task runner, to handle the concatenation and minification. We also use a plugin gulp-rev to automatically rename the file based on the contents to give it a unique name like styles-j2l3zYq59kj.css.\n\nThe challenge, therefore, is how to get this always-changing filename into our markup for delivery to the user?  One option is gulp-inject which will update the HTML with the new CSS/JS filenames but this causes noisy commits. Instead, we created this very lightweight asset manager which reads a JSON file and translates from original to cachebusted name:\n\n    \u003clink rel=\"stylesheet\" href=\"#asset.getAsset('style.css')#\"\u003e\n    outputs\n    \u003clink rel=\"stylesheet\" href=\"styles-j2l3zYq59kj.css\"\u003e\n\n# Generate rev-manifest.json\n\nYou can generate your manifest file many ways. We do it as part of a Gulp build pipeline that regenerates this file every time we modify a CSS or JS file. We have used https://www.npmjs.com/package/gulp-asset-manifest but currently use our own routine (in JS):\n\n    app.createManifest = function(assets, ignorePath) {\n    \tvar files = fs.readdirSync(assets);\n    \tvar relpath = app.removeBasePath(ignorePath, assets);\n    \tvar matches = {};\n    \n    \tfor (var ii = 0; ii \u003c files.length; ii++) {\n    \t\tvar f = files[ii];\n    \t\tvar ext = path.extname(f);\n    \t\tif (ext == '.js' || ext == '.css') {\n    \t\t\t// gulp-rev generates files like base-name-file-0123456789.ext where the hash is always 10 characters - we want everything up to that last hyphen before the hash\n    \t\t\tmatches[path.basename(f, ext).slice(0, -11) + ext] = relpath + f;\n    \t\t}\n    \t}\n    \n    \t// the 4 here causes it to pretty print the file for readability \n    \tfs.writeFileSync(assets + '/rev-manifest.json', JSON.stringify(matches, null, 4), 'utf-8');\n    };\n\n# Application.cfc\n\nDuring init (e.g. onApplicationStart), create the asset manager and feed it your manifest file:\n\n    \u003ccfif NOT structKeyExists(application, \"assets\")\u003e\n        \u003ccfset application.assets = createObject(\"component\", \"assets\").init() /\u003e\n    \u003c/cfif\u003e\n    \u003ccfset application.assets.loadManifest(expandPath('./rev-manifest.json') /\u003e\n\nNow in your HTML, you can output CSS/JS includes:\n\n    \u003clink rel=\"stylesheet\" href=\"#application.assets.getAsset('style.css')#\"\u003e \n    \u003cscript src=\"#application.assets.getAsset('core.js')#\"\u003e\u003c/script\u003e\n    \n# Development Mode\n\nDuring development, use a flag to reload the manifest file on each request to catch updated filenames in onRequestStart like:\n\n    \u003ccffunction name=\"onRequestStart\" access=\"public\" returntype=\"void\" output=\"false\"\u003e\n\t\t  \u003ccfif TESTMODE\u003e\n\t\t\t  \u003ccfset loadAssetManifest() /\u003e\n\t\t  \u003c/cfif\u003e\n    \u003c/cffunction\u003e\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghidinelli%2Fassets.cfc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghidinelli%2Fassets.cfc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghidinelli%2Fassets.cfc/lists"}