[{"data":1,"prerenderedAt":712},["ShallowReactive",2],{"post:switching-to-cfscript":3},{"id":4,"title":5,"body":6,"date":698,"description":699,"draft":700,"extension":701,"meta":702,"navigation":703,"path":704,"seo":705,"stem":706,"tags":707,"__hash__":711},"posts\u002Fposts\u002Fswitching-to-cfscript.md","Switching from Tag to Script",{"type":7,"value":8,"toc":687},"minimark",[9,13,22,27,30,43,47,50,180,183,266,269,273,276,280,299,302,461,468,500,503,507,510,550,555,562,569,578,582,598,634,637,651,654,668,672,683],[10,11,5],"h1",{"id":12},"switching-from-tag-to-script",[14,15,16,17,21],"p",{},"Look, I write in CFScript. Most of the CF devs I look up to write in CFScript. But maybe you don't. Here's where I convince you CFScript is worth the jump and, for that matter, just ",[18,19,20],"em",{},"how"," to \"jump\" to CFScript.",[23,24,26],"h2",{"id":25},"why-switch-to-cfscript","Why Switch to CFScript",[14,28,29],{},"Why on earth would you want to convert your app to script syntax? I can think of three main reasons:",[31,32,33,37,40],"ol",{},[34,35,36],"li",{},"Script syntax is more condensed (shorter) and thus quicker to read and write",[34,38,39],{},"Most CF open source packages are in script syntax, making it harder to find useful tag syntax snippets",[34,41,42],{},"Paradigm shift into proper separation of logic and presentation",[23,44,46],{"id":45},"script-syntax-is-more-condensed","Script Syntax is More Condensed",[14,48,49],{},"Compare this simple UDF in tag syntax:",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-html shiki shiki-themes github-light github-dark","\u003Ccffunction name=\"renderView\" returnType=\"void\" access=\"private\" hint=\"Render a CFM template in the views folder.\">\n    \u003Ccfargument name=\"filename\" type=\"string\" required=\"true\" hint=\"the name of the file to execute with NO .cfm on the end.\">\n    \u003Ccfinclude template=\"#getViewsFolder() & arguments.filename#.cfm\">\n\u003C\u002Fcffunction>\n","html","",[58,59,60,111,152,170],"code",{"__ignoreMap":56},[61,62,65,69,73,77,80,84,87,89,92,95,97,100,103,105,108],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"sVt8B","\u003C",[61,70,72],{"class":71},"s7hpK","cffunction",[61,74,76],{"class":75},"sScJk"," name",[61,78,79],{"class":67},"=",[61,81,83],{"class":82},"sZZnC","\"renderView\"",[61,85,86],{"class":75}," returnType",[61,88,79],{"class":67},[61,90,91],{"class":82},"\"void\"",[61,93,94],{"class":75}," access",[61,96,79],{"class":67},[61,98,99],{"class":82},"\"private\"",[61,101,102],{"class":75}," hint",[61,104,79],{"class":67},[61,106,107],{"class":82},"\"Render a CFM template in the views folder.\"",[61,109,110],{"class":67},">\n",[61,112,114,117,120,122,124,127,130,132,135,138,140,143,145,147,150],{"class":63,"line":113},2,[61,115,116],{"class":67},"    \u003C",[61,118,119],{"class":71},"cfargument",[61,121,76],{"class":75},[61,123,79],{"class":67},[61,125,126],{"class":82},"\"filename\"",[61,128,129],{"class":75}," type",[61,131,79],{"class":67},[61,133,134],{"class":82},"\"string\"",[61,136,137],{"class":75}," required",[61,139,79],{"class":67},[61,141,142],{"class":82},"\"true\"",[61,144,102],{"class":75},[61,146,79],{"class":67},[61,148,149],{"class":82},"\"the name of the file to execute with NO .cfm on the end.\"",[61,151,110],{"class":67},[61,153,155,157,160,163,165,168],{"class":63,"line":154},3,[61,156,116],{"class":67},[61,158,159],{"class":71},"cfinclude",[61,161,162],{"class":75}," template",[61,164,79],{"class":67},[61,166,167],{"class":82},"\"#getViewsFolder() & arguments.filename#.cfm\"",[61,169,110],{"class":67},[61,171,173,176,178],{"class":63,"line":172},4,[61,174,175],{"class":67},"\u003C\u002F",[61,177,72],{"class":71},[61,179,110],{"class":67},[14,181,182],{},"vs. script syntax:",[51,184,188],{"className":185,"code":186,"language":187,"meta":56,"style":56},"language-js shiki shiki-themes github-light github-dark","\u002F**\n * Render a CFM template in the views folder.\n * @filename the name of the file to execute with NO .cfm on the end.\n*\u002F\nprivate void function renderView( required string filename ) {\n    include \"#getViewsFolder() & arguments.filename#.cfm\";\n}\n","js",[58,189,190,196,201,213,218,249,260],{"__ignoreMap":56},[61,191,192],{"class":63,"line":64},[61,193,195],{"class":194},"sJ8bj","\u002F**\n",[61,197,198],{"class":63,"line":113},[61,199,200],{"class":194}," * Render a CFM template in the views folder.\n",[61,202,203,206,210],{"class":63,"line":154},[61,204,205],{"class":194}," * ",[61,207,209],{"class":208},"szBVR","@filename",[61,211,212],{"class":194}," the name of the file to execute with NO .cfm on the end.\n",[61,214,215],{"class":63,"line":172},[61,216,217],{"class":194},"*\u002F\n",[61,219,221,224,227,230,233,236,240,243,246],{"class":63,"line":220},5,[61,222,223],{"class":67},"private ",[61,225,226],{"class":208},"void",[61,228,229],{"class":208}," function",[61,231,232],{"class":75}," renderView",[61,234,235],{"class":67},"( ",[61,237,239],{"class":238},"s4XuR","required",[61,241,242],{"class":238}," string",[61,244,245],{"class":238}," filename",[61,247,248],{"class":67}," ) {\n",[61,250,252,255,257],{"class":63,"line":251},6,[61,253,254],{"class":67},"    include ",[61,256,167],{"class":82},[61,258,259],{"class":67},";\n",[61,261,263],{"class":63,"line":262},7,[61,264,265],{"class":67},"}\n",[14,267,268],{},"The difference is clear: Script syntax is shorter, cleaner, and easier to read. I understand there may be a few instances where tag syntax is more clear and explicit, but... well... I can't think of any!",[23,270,272],{"id":271},"more-open-source-packages-and-snippets-in-script-syntax","More Open Source Packages and Snippets in Script Syntax",[14,274,275],{},"Besides the syntactical differences, script syntax is preferred by most modern CF devs and open source packages these days. So it'll be harder to pick up a new tool or code snippet if you don't know script syntax or your app is still in tags.",[23,277,279],{"id":278},"the-paradigm-shift-separation-of-logic-and-presentation","The Paradigm Shift: Separation of Logic and Presentation",[14,281,282,283,290,291,294,295,298],{},"CF has been plagued by a ",[284,285,289],"a",{"href":286,"rel":287},"https:\u002F\u002Fmichaelborn.me\u002Fentry\u002Fcf-a-legacy-of-legacy",[288],"nofollow","\"legacy of legacy\"",", and much of that has to do with embedding queries, business logic, and HTML (presentation) into a single .cfm file. This poor programming practice rests largely on the heads of cowboy coders, but I posit this spaghetti mess is all made possible by the sheer existence of CFML's tag syntax. Because it ",[18,292,293],{},"looks"," like HTML, devs tended to keep their queries, ifs and loops ",[18,296,297],{},"with"," their HTML, and the \"pot of leftovers\"-like programming paradigm was born.",[14,300,301],{},"Today, devs can alter that paradigm by switching to CFScript. Writing in script syntax forces devs to change the way they output HTML. Believe me, one week of this:",[51,303,305],{"className":185,"code":304,"language":187,"meta":56,"style":56},"function renderEmail( string args ) {\n    writeOutput('\n        \u003Chtml>\n        \u003Chead>\n          \u003Ctitle>#args.title#\u003C\u002Ftitle>\n        \u003C\u002Fhead>\n        \u003Cbody>\n        \u003Cul>\n    ');\n    for( var person in args.people ) {\n        writeOutput('#person.name# did something');\n    }\n    writeOutput('\u003C\u002Ful>\u003C\u002Fbody>\u003C\u002Fhtml>');\n}\n",[58,306,307,325,336,343,354,369,378,387,397,403,409,423,429,456],{"__ignoreMap":56},[61,308,309,312,315,317,320,323],{"class":63,"line":64},[61,310,311],{"class":208},"function",[61,313,314],{"class":75}," renderEmail",[61,316,235],{"class":67},[61,318,319],{"class":238},"string",[61,321,322],{"class":238}," args",[61,324,248],{"class":67},[61,326,327,330,333],{"class":63,"line":113},[61,328,329],{"class":75},"    writeOutput",[61,331,332],{"class":67},"(",[61,334,335],{"class":82},"'\n",[61,337,338,341],{"class":63,"line":154},[61,339,340],{"class":82},"        \u003Chtml",[61,342,110],{"class":71},[61,344,345,348,352],{"class":63,"line":172},[61,346,347],{"class":67},"        \u003C",[61,349,351],{"class":350},"s9eBZ","head",[61,353,110],{"class":67},[61,355,356,359,362,365,367],{"class":63,"line":220},[61,357,358],{"class":67},"          \u003C",[61,360,361],{"class":350},"title",[61,363,364],{"class":67},">#args.title#\u003C\u002F",[61,366,361],{"class":350},[61,368,110],{"class":67},[61,370,371,374,376],{"class":63,"line":251},[61,372,373],{"class":67},"        \u003C\u002F",[61,375,351],{"class":350},[61,377,110],{"class":67},[61,379,380,382,385],{"class":63,"line":262},[61,381,347],{"class":67},[61,383,384],{"class":350},"body",[61,386,110],{"class":67},[61,388,390,392,395],{"class":63,"line":389},8,[61,391,347],{"class":67},[61,393,394],{"class":350},"ul",[61,396,110],{"class":67},[61,398,400],{"class":63,"line":399},9,[61,401,402],{"class":67},"    ');\n",[61,404,406],{"class":63,"line":405},10,[61,407,408],{"class":67},"    for( var person in args.people ) {\n",[61,410,412,415,417,420],{"class":63,"line":411},11,[61,413,414],{"class":75},"        writeOutput",[61,416,332],{"class":67},[61,418,419],{"class":82},"'#person.name# did something'",[61,421,422],{"class":67},");\n",[61,424,426],{"class":63,"line":425},12,[61,427,428],{"class":67},"    }\n",[61,430,432,435,437,440,442,445,447,449,451,454],{"class":63,"line":431},13,[61,433,434],{"class":67},"    writeOutput('\u003C\u002F",[61,436,394],{"class":350},[61,438,439],{"class":67},">\u003C\u002F",[61,441,384],{"class":350},[61,443,444],{"class":67},">",[61,446,175],{"class":208},[61,448,55],{"class":67},[61,450,444],{"class":208},[61,452,453],{"class":82},"')",[61,455,259],{"class":71},[61,457,459],{"class":63,"line":458},14,[61,460,265],{"class":67},[14,462,463,464,467],{},"and you will quickly be dumping that HTML into a ",[58,465,466],{},".cfm"," file and writing this instead:",[51,469,471],{"className":185,"code":470,"language":187,"meta":56,"style":56},"function renderEmail( string args ) {\n    include \"views\u002Femail.cfm\";\n}\n",[58,472,473,487,496],{"__ignoreMap":56},[61,474,475,477,479,481,483,485],{"class":63,"line":64},[61,476,311],{"class":208},[61,478,314],{"class":75},[61,480,235],{"class":67},[61,482,319],{"class":238},[61,484,322],{"class":238},[61,486,248],{"class":67},[61,488,489,491,494],{"class":63,"line":113},[61,490,254],{"class":67},[61,492,493],{"class":82},"\"views\u002Femail.cfm\"",[61,495,259],{"class":67},[61,497,498],{"class":63,"line":154},[61,499,265],{"class":67},[14,501,502],{},"Ta-da! Instantly you have started down the path of proper MVC.",[23,504,506],{"id":505},"converting-to-script","Converting to Script",[14,508,509],{},"So if you want to make \"the jump\" and convert your existing apps to CFscript, here's what I would do:",[31,511,512,528,535,541],{},[34,513,514,515,518,519,523,524,527],{},"Don't blindly convert ",[18,516,517],{},"everything"," to script syntax unless you you have a ",[520,521,522],"strong",{},"very"," solid test suite in place and you are ",[18,525,526],{},"willing to break stuff",".",[34,529,530,531,534],{},"Start by converting single functions in your CFCs. Stick a big ole ",[58,532,533],{},"\u003Ccfscript>\u003C\u002Fcfscript>"," in there and each time you edit or refactor a function, simply convert it to script syntax and drop it in the script block. You can use cfscript.me for this (see below) or rewrite it by hand.",[34,536,537,538,540],{},"Don't convert your HTML templates to script! Instead, separate the logic out into a separate file (preferably a class) in script syntax. Leave all HTML-generating code (in a ",[58,539,466],{}," file) in tag syntax.",[34,542,543,544,549],{},"Once larger portions of your app have been converted, consider using the ",[284,545,548],{"href":546,"rel":547},"https:\u002F\u002Fwww.forgebox.io\u002Fview\u002Fcfscriptme-command",[288],"cfscript.me command"," to convert the rest of your app to script syntax.",[551,552,554],"h3",{"id":553},"cfscriptme","CFScript.me",[14,556,557,561],{},[284,558,554],{"href":559,"rel":560},"http:\u002F\u002Fcfscript.me",[288]," is a great tool for manually converting individual files and smaller snippets of code from tag to script syntax.",[14,563,564],{},[565,566],"img",{"alt":567,"src":568},"Screenshot of cfscript.me website with a block of tag syntax code on the left and generated script syntax on the right","https:\u002F\u002Fthepracticaldev.s3.amazonaws.com\u002Fi\u002Fk20ucmcqsa2pwqzkm8k5.png",[14,570,571,572,577],{},"CFSript.me works well for smaller blocks of code, although it is not feature-complete (has a number of ",[284,573,576],{"href":574,"rel":575},"https:\u002F\u002Fgithub.com\u002Ffoundeo\u002Ftoscript\u002Fissues",[288],"outstanding issues"," with unsupported tag syntax).",[551,579,581],{"id":580},"cfscriptme-command","CFScriptMe Command",[14,583,584,585,589,590,593,594,597],{},"If you've got a whole project you need to convert to script syntax, I would use the ",[284,586,588],{"href":546,"rel":587},[288],"CFScriptMe"," CLI command . ",[520,591,592],{},"Please"," do not run this without (1) a backup in Git, and (2) a test suite to verify the code actually ",[18,595,596],{},"works"," when you're done. As a third sanity check, use CFLint to lint your script syntax when you are done.",[51,599,603],{"className":600,"code":601,"language":602,"meta":56,"style":56},"language-bash shiki shiki-themes github-light github-dark","box install cfscriptme-command\nbox cfscriptme \u003Cpath>\n","bash",[58,604,605,616],{"__ignoreMap":56},[61,606,607,610,613],{"class":63,"line":64},[61,608,609],{"class":75},"box",[61,611,612],{"class":82}," install",[61,614,615],{"class":82}," cfscriptme-command\n",[61,617,618,620,623,626,629,632],{"class":63,"line":113},[61,619,609],{"class":75},[61,621,622],{"class":82}," cfscriptme",[61,624,625],{"class":208}," \u003C",[61,627,628],{"class":82},"pat",[61,630,631],{"class":67},"h",[61,633,110],{"class":208},[14,635,636],{},"You can run cfscriptme-command on a single file:",[51,638,640],{"className":600,"code":639,"language":602,"meta":56,"style":56},"box cfscriptme cfc\u002FmyFile.cfc\n",[58,641,642],{"__ignoreMap":56},[61,643,644,646,648],{"class":63,"line":64},[61,645,609],{"class":75},[61,647,622],{"class":82},[61,649,650],{"class":82}," cfc\u002FmyFile.cfc\n",[14,652,653],{},"or on an entire folder:",[51,655,657],{"className":600,"code":656,"language":602,"meta":56,"style":56},"box cfscriptme models\n",[58,658,659],{"__ignoreMap":56},[61,660,661,663,665],{"class":63,"line":64},[61,662,609],{"class":75},[61,664,622],{"class":82},[61,666,667],{"class":82}," models\n",[23,669,671],{"id":670},"conclusion","Conclusion",[14,673,674,675,678,679,682],{},"You do not ",[520,676,677],{},"have"," to switch to CFScript. But I ",[520,680,681],{},"highly"," recommend it for the reasons outlined in this article. If you need help switching to CFScript, reach out and let me know. If you have other thoughts on this article, there's a comment form at the bottom. Thanks for reading!",[684,685,686],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":56,"searchDepth":113,"depth":113,"links":688},[689,690,691,692,693,697],{"id":25,"depth":113,"text":26},{"id":45,"depth":113,"text":46},{"id":271,"depth":113,"text":272},{"id":278,"depth":113,"text":279},{"id":505,"depth":113,"text":506,"children":694},[695,696],{"id":553,"depth":154,"text":554},{"id":580,"depth":154,"text":581},{"id":670,"depth":113,"text":671},"2019-06-26T16:13:57-04:00","Look, I write in CFScript. Most of the CF devs I look up to write in CFScript. But maybe you don't. Here's where I convince you CFScript is worth the jump and, for that matter, just how to \"jump\" to CFScript.",false,"md",{},true,"\u002Fposts\u002Fswitching-to-cfscript",{"title":5,"description":699},"posts\u002Fswitching-to-cfscript",[708,709,710],"coldfusion","cfml","cfscript","dTOiAyFTOkV1cBRR5FUcTOeoR6jJVVmfT0nyHpIU8z4",1790471527805]