PageRenderTime 124ms CodeModel.GetById 81ms app.highlight 3ms RepoModel.GetById 37ms app.codeStats 0ms

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