/wheels/view/assets.cfm

http://cfwheels.googlecode.com/ · ColdFusion · 269 lines · 255 code · 14 blank · 0 comment · 45 complexity · ee7ab90d22e913f0be7868b15b9c9f86 MD5 · raw file

  1. <cffunction name="styleSheetLinkTag" returntype="string" access="public" output="false" hint="Returns a `link` tag for a stylesheet (or several) based on the supplied arguments."
  2. examples=
  3. '
  4. <!--- view code --->
  5. <head>
  6. <!--- Includes `stylesheets/styles.css` --->
  7. ##styleSheetLinkTag("styles")##
  8. <!--- Includes `stylesheets/blog.css` and `stylesheets/comments.css` --->
  9. ##styleSheetLinkTag("blog,comments")##
  10. <!--- Includes printer style sheet --->
  11. ##styleSheetLinkTag(source="print", media="print")##
  12. <!--- Includes external style sheet --->
  13. ##styleSheetLinkTag("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/cupertino/jquery-ui.css")##
  14. </head>
  15. <body>
  16. <!--- This will still appear in the `head` --->
  17. ##styleSheetLinkTag(source="tabs", head=true)##
  18. </body>
  19. '
  20. categories="view-helper,assets" chapters="miscellaneous-helpers" functions="javaScriptIncludeTag,imageTag">
  21. <cfargument name="sources" type="string" required="false" default="" hint="The name of one or many CSS files in the `stylesheets` folder, minus the `.css` extension. (Can also be called with the `source` argument.) Pass a full URL to generate a tag for an external style sheet.">
  22. <cfargument name="type" type="string" required="false" hint="The `type` attribute for the `link` tag.">
  23. <cfargument name="media" type="string" required="false" hint="The `media` attribute for the `link` tag.">
  24. <cfargument name="head" type="string" required="false" hint="Set to `true` to place the output in the `head` area of the HTML page instead of the default behavior, which is to place the output where the function is called from.">
  25. <cfscript>
  26. var loc = {};
  27. $args(name="styleSheetLinkTag", args=arguments, combine="sources/source/!", reserved="href,rel");
  28. arguments.rel = "stylesheet";
  29. loc.returnValue = "";
  30. arguments.sources = $listClean(list=arguments.sources, returnAs="array");
  31. loc.iEnd = ArrayLen(arguments.sources);
  32. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  33. {
  34. loc.item = arguments.sources[loc.i];
  35. if (ReFindNoCase("^https?:\/\/", loc.item))
  36. {
  37. arguments.href = arguments.sources[loc.i];
  38. }
  39. else
  40. {
  41. arguments.href = application.wheels.webPath & application.wheels.stylesheetPath & "/" & loc.item;
  42. if (!ListFindNoCase("css,cfm", ListLast(loc.item, ".")))
  43. arguments.href = arguments.href & ".css";
  44. arguments.href = $assetDomain(arguments.href) & $appendQueryString();
  45. }
  46. loc.returnValue = loc.returnValue & $tag(name="link", skip="sources,head", close=true, attributes=arguments) & chr(10);
  47. }
  48. if (arguments.head)
  49. {
  50. $htmlhead(text=loc.returnValue);
  51. loc.returnValue = "";
  52. }
  53. </cfscript>
  54. <cfreturn loc.returnValue>
  55. </cffunction>
  56. <cffunction name="javaScriptIncludeTag" returntype="string" access="public" output="false" hint="Returns a `script` tag for a JavaScript file (or several) based on the supplied arguments."
  57. examples=
  58. '
  59. <!--- view code --->
  60. <head>
  61. <!--- Includes `javascripts/main.js` --->
  62. ##javaScriptIncludeTag("main")##
  63. <!--- Includes `javascripts/blog.js` and `javascripts/accordion.js` --->
  64. ##javaScriptIncludeTag("blog,accordion")##
  65. <!--- Includes external JavaScript file --->
  66. ##javaScriptIncludeTag("https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js")##
  67. </head>
  68. <body>
  69. <!--- Will still appear in the `head` --->
  70. ##javaScriptIncludeTag(source="tabs", head=true)##
  71. </body>
  72. '
  73. categories="view-helper,assets" chapters="miscellaneous-helpers" functions="styleSheetLinkTag,imageTag">
  74. <cfargument name="sources" type="string" required="false" default="" hint="The name of one or many JavaScript files in the `javascripts` folder, minus the `.js` extension. (Can also be called with the `source` argument.) Pass a full URL to access an external JavaScript file.">
  75. <cfargument name="type" type="string" required="false" hint="The `type` attribute for the `script` tag.">
  76. <cfargument name="head" type="string" required="false" hint="See documentation for @styleSheetLinkTag.">
  77. <cfscript>
  78. var loc = {};
  79. $args(name="javaScriptIncludeTag", args=arguments, combine="sources/source/!", reserved="src");
  80. loc.returnValue = "";
  81. arguments.sources = $listClean(list=arguments.sources, returnAs="array");
  82. loc.iEnd = ArrayLen(arguments.sources);
  83. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  84. {
  85. loc.item = arguments.sources[loc.i];
  86. if (ReFindNoCase("^https?:\/\/", loc.item))
  87. {
  88. arguments.src = arguments.sources[loc.i];
  89. }
  90. else
  91. {
  92. arguments.src = application.wheels.webPath & application.wheels.javascriptPath & "/" & loc.item;
  93. if (!ListFindNoCase("js,cfm", ListLast(loc.item, ".")))
  94. arguments.src = arguments.src & ".js";
  95. arguments.src = $assetDomain(arguments.src) & $appendQueryString();
  96. }
  97. loc.returnValue = loc.returnValue & $element(name="script", skip="sources,head", attributes=arguments) & chr(10);
  98. }
  99. if (arguments.head)
  100. {
  101. $htmlhead(text=loc.returnValue);
  102. loc.returnValue = "";
  103. }
  104. </cfscript>
  105. <cfreturn loc.returnValue>
  106. </cffunction>
  107. <cffunction name="imageTag" returntype="string" access="public" output="false" hint="Returns an `img` tag. If the image is stored in the local `images` folder, the tag will also set the `width`, `height`, and `alt` attributes for you. Note: Pass any additional arguments like `class`, `rel`, and `id`, and the generated tag will also include those values as HTML attributes."
  108. examples=
  109. '
  110. <!--- Outputs an `img` tag for `images/logo.png` --->
  111. ##imageTag("logo.png")##
  112. <!--- Outputs an `img` tag for `http://cfwheels.org/images/logo.png` --->
  113. ##imageTag("http://cfwheels.org/images/logo.png", alt="ColdFusion on Wheels")##
  114. <!--- Outputs an `img` tag with the `class` attribute set --->
  115. ##imageTag(source="logo.png", class="logo")##
  116. '
  117. categories="view-helper,assets" chapters="miscellaneous-helpers" functions="javaScriptIncludeTag,styleSheetLinkTag">
  118. <cfargument name="source" type="string" required="true" hint="The file name of the image if it's availabe in the local file system (i.e. ColdFusion will be able to access it). Provide the full URL if the image is on a remote server.">
  119. <cfscript>
  120. var loc = {};
  121. $args(name="imageTag", reserved="src", args=arguments);
  122. // ugly fix due to the fact that id can't be passed along to cfinvoke
  123. if (StructKeyExists(arguments, "id"))
  124. {
  125. arguments.wheelsId = arguments.id;
  126. StructDelete(arguments, "id");
  127. }
  128. if (application.wheels.cacheImages)
  129. {
  130. loc.category = "images";
  131. loc.key = $hashedKey(arguments);
  132. loc.lockName = loc.category & loc.key;
  133. loc.conditionArgs = {};
  134. loc.conditionArgs.category = loc.category;
  135. loc.conditionArgs.key = loc.key;
  136. loc.executeArgs = arguments;
  137. loc.executeArgs.category = loc.category;
  138. loc.executeArgs.key = loc.key;
  139. loc.returnValue = $doubleCheckedLock(name=loc.lockName, condition="$getFromCache", execute="$addImageTagToCache", conditionArgs=loc.conditionArgs, executeArgs=loc.executeArgs);
  140. }
  141. else
  142. {
  143. loc.returnValue = $imageTag(argumentCollection=arguments);
  144. }
  145. // ugly fix continued
  146. if (StructKeyExists(arguments, "wheelsId"))
  147. loc.returnValue = ReplaceNoCase(loc.returnValue, "wheelsId", "id");
  148. </cfscript>
  149. <cfreturn loc.returnValue>
  150. </cffunction>
  151. <cffunction name="$addImageTagToCache" returntype="string" access="public" output="false">
  152. <cfscript>
  153. var returnValue = "";
  154. returnValue = $imageTag(argumentCollection=arguments);
  155. $addToCache(key=arguments.key, value=returnValue, category=arguments.category);
  156. </cfscript>
  157. <cfreturn returnValue>
  158. </cffunction>
  159. <cffunction name="$imageTag" returntype="string" access="public" output="false">
  160. <cfscript>
  161. var loc = {};
  162. loc.localFile = true;
  163. if(Left(arguments.source, 7) == "http://" || Left(arguments.source, 8) == "https://")
  164. loc.localFile = false;
  165. if (!loc.localFile)
  166. {
  167. arguments.src = arguments.source;
  168. }
  169. else
  170. {
  171. arguments.src = application.wheels.webPath & application.wheels.imagePath & "/" & arguments.source;
  172. if (application.wheels.showErrorInformation)
  173. {
  174. if (loc.localFile && !FileExists(ExpandPath(arguments.src)))
  175. $throw(type="Wheels.ImageFileNotFound", message="Wheels could not find `#expandPath('#arguments.src#')#` on the local file system.", extendedInfo="Pass in a correct relative path from the `images` folder to an image.");
  176. else if (!IsImageFile(ExpandPath(arguments.src)))
  177. $throw(type="Wheels.ImageFormatNotSupported", message="Wheels can't read image files with that format.", extendedInfo="Use one of these image types instead: #GetReadableImageFormats()#.");
  178. }
  179. // height and/or width arguments are missing so use cfimage to get them
  180. if (!StructKeyExists(arguments, "width") or !StructKeyExists(arguments, "height"))
  181. {
  182. loc.image = $image(action="info", source=ExpandPath(arguments.src));
  183. if (!StructKeyExists(arguments, "width") and loc.image.width gt 0)
  184. arguments.width = loc.image.width;
  185. if (!StructKeyExists(arguments, "height") and loc.image.height gt 0)
  186. arguments.height = loc.image.height;
  187. }
  188. // only append a query string if the file is local
  189. arguments.src = $assetDomain(arguments.src) & $appendQueryString();
  190. }
  191. if (!StructKeyExists(arguments, "alt"))
  192. arguments.alt = capitalize(ReplaceList(SpanExcluding(Reverse(SpanExcluding(Reverse(arguments.src), "/")), "."), "-,_", " , "));
  193. loc.returnValue = $tag(name="img", skip="source,key,category", close=true, attributes=arguments);
  194. </cfscript>
  195. <cfreturn loc.returnValue>
  196. </cffunction>
  197. <cffunction name="$appendQueryString" returntype="string" access="public" output="false">
  198. <cfscript>
  199. var returnValue = "";
  200. // if assetQueryString is a boolean value, it means we just reloaded, so create a new query string based off of now
  201. // the only problem with this is if the app doesn't get used a lot and the application is left alone for a period longer than the application scope is allowed to exist
  202. if (IsBoolean(application.wheels.assetQueryString) and YesNoFormat(application.wheels.assetQueryString) == "no")
  203. return returnValue;
  204. if (!IsNumeric(application.wheels.assetQueryString) and IsBoolean(application.wheels.assetQueryString))
  205. application.wheels.assetQueryString = Hash(DateFormat(Now(), "yyyymmdd") & TimeFormat(Now(), "HHmmss"));
  206. returnValue = returnValue & "?" & application.wheels.assetQueryString;
  207. </cfscript>
  208. <cfreturn returnValue />
  209. </cffunction>
  210. <cffunction name="$assetDomain" returntype="string" access="public" output="false">
  211. <cfargument name="pathToAsset" type="string" required="true">
  212. <cfscript>
  213. var loc = {};
  214. loc.returnValue = arguments.pathToAsset;
  215. if (application.wheels.showErrorInformation)
  216. {
  217. if (!IsStruct(application.wheels.assetPaths) && !IsBoolean(application.wheels.assetPaths))
  218. $throw(type="Wheels.IncorrectConfiguration", message="The setting `assetsPaths` must be false or a struct.");
  219. if (IsStruct(application.wheels.assetPaths) && !ListFindNoCase(StructKeyList(application.wheels.assetPaths), "http"))
  220. $throw(type="Wheels.IncorrectConfiguration", message="The `assetPaths` setting struct must contain the key `http`");
  221. }
  222. // return nothing if assetPaths is not a struct
  223. if (!IsStruct(application.wheels.assetPaths))
  224. return loc.returnValue;
  225. loc.protocol = "http://";
  226. loc.domainList = application.wheels.assetPaths.http;
  227. if (isSecure())
  228. {
  229. loc.protocol = "https://";
  230. if (StructKeyExists(application.wheels.assetPaths, "https"))
  231. loc.domainList = application.wheels.assetPaths.https;
  232. }
  233. loc.domainLen = ListLen(loc.domainList);
  234. if (loc.domainLen gt 1)
  235. {
  236. // now comes the interesting part, lets take the pathToAsset argument, hash it and create a number from it
  237. // so that we can do mod based off the length of the domain list
  238. // this is an easy way to apply the same sub-domain to each asset, so we do not create more work for the server
  239. // at the same time we are getting a very random hash value to rotate the domains over the assets evenly
  240. loc.pathNumber = Right(REReplace(Hash(arguments.pathToAsset), "[A-Za-z]", "", "all"), 5);
  241. loc.position = (loc.pathNumber mod (loc.domainLen)) + 1;
  242. }
  243. else
  244. {
  245. loc.position = loc.domainLen;
  246. }
  247. loc.returnValue = loc.protocol & Trim(ListGetAt(loc.domainList, loc.position)) & arguments.pathToAsset;
  248. </cfscript>
  249. <cfreturn loc.returnValue />
  250. </cffunction>