PageRenderTime 36ms CodeModel.GetById 23ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/wheels/view/miscellaneous.cfm

http://raihan.googlecode.com/
ColdFusion | 471 lines | 433 code | 25 blank | 13 comment | 35 complexity | 7a0f2b9109c8e08b3788b000af756ccd MD5 | raw file
  1<cffunction name="contentFor" returntype="void" access="public" output="false" hint="Used to store a section's output for rendering within a layout. This content store acts as a stack, so you can store multiple pieces of content for a given section."
  2	examples=
  3	'	
  4		<!--- In your view --->
  5		<cfsavecontent variable="mySidebar">
  6		<h1>My Sidebar Text</h1>
  7		</cfsavecontent>
  8		<cfset contentFor(sidebar=mySidebar)>
  9		
 10		<!--- In your layout --->
 11		<html>
 12		<head>
 13		    <title>My Site</title>
 14		</head>
 15		<body>
 16		
 17		<cfoutput>
 18		##includeContent("sidebar")##
 19		
 20		##includeContent()##
 21		</cfoutput>
 22
 23		</body>
 24		</html>
 25	'
 26	categories="view-helper,miscellaneous" chapters="">
 27	<cfargument name="position" type="any" required="false" default="last" hint="The position in the section's stack where you want the content placed. Valid values are `first`, `last`, or the numeric position.">
 28	<cfargument name="overwrite" type="any" required="false" default="false" hint="Whether or not to overwrite any of the content. Valid values are `false`, `true`, or `all`.">
 29	<cfset var loc = {}>
 30	
 31	<!--- position in the array for the content --->
 32	<cfset loc.position = "last">
 33	<!--- should we overwrite or insert into the array --->
 34	<cfset loc.overwrite = "false">
 35	
 36	<!--- extract optional arguments --->
 37	<cfif StructKeyExists(arguments, "position")>
 38		<cfset loc.position = arguments.position>
 39		<cfset StructDelete(arguments, "position", false)>
 40	</cfif>
 41	
 42	<cfif StructKeyExists(arguments, "overwrite")>
 43		<cfset loc.overwrite = arguments.overwrite>
 44		<cfset StructDelete(arguments, "overwrite", false)>
 45	</cfif>
 46	
 47	<!--- if no other arguments exists, exit --->
 48	<cfif StructIsEmpty(arguments)>
 49		<cfreturn>
 50	</cfif>
 51	
 52	<!--- since we're not going to know the name of the section, we have to get it dynamically --->
 53	<cfset loc.section = ListFirst(StructKeyList(arguments))>
 54	<cfset loc.content = arguments[loc.section]>
 55	
 56	<cfif !IsBoolean(loc.overwrite)>
 57		<cfset loc.overwrite = "all">
 58	</cfif>
 59	
 60	<cfif !StructKeyExists(variables.$instance.contentFor, loc.section) OR loc.overwrite eq "all">
 61		<!--- if the section doesn't exists, or they want to overwrite the whole thing --->
 62		<cfset variables.$instance.contentFor[loc.section] = []>
 63		<cfset ArrayAppend(variables.$instance.contentFor[loc.section], loc.content)>
 64	<cfelse>
 65		<cfset loc.size = ArrayLen(variables.$instance.contentFor[loc.section])>
 66		<!--- they want to append, prepend or insert at a specific point in the array --->
 67		<!--- make sure position is within range --->
 68		<cfif !IsNumeric(loc.position) AND !ListFindNoCase("first,last", loc.position)>
 69			<cfset loc.position = "last">
 70		</cfif>
 71		<cfif IsNumeric(loc.position)>
 72			<cfif loc.position lte 1>
 73				<cfset loc.position = "first">
 74			<cfelseif loc.position gte loc.size>
 75				<cfset loc.position = "last">
 76			</cfif>
 77		</cfif>
 78
 79		<cfif loc.overwrite>
 80			<cfif loc.position is "last">
 81				<cfset loc.position = loc.size>
 82			<cfelseif loc.position is "first">
 83				<cfset loc.position = 1>
 84			</cfif>
 85			<cfset variables.$instance.contentFor[loc.section][loc.position] = loc.content>
 86		<cfelse>
 87			<cfif loc.position is "last">
 88				<cfset ArrayAppend(variables.$instance.contentFor[loc.section], loc.content)>
 89			<cfelseif loc.position is "first">
 90				<cfset ArrayPrepend(variables.$instance.contentFor[loc.section], loc.content)>
 91			<cfelse>
 92				<cfset ArrayInsertAt(variables.$instance.contentFor[loc.section], loc.position, loc.content)>
 93			</cfif>
 94		</cfif>			
 95	</cfif>
 96</cffunction>
 97
 98<cffunction name="includeLayout" returntype="string" access="public" output="false" hint="Includes the contents of another layout file. This is usually used to include a parent layout from within a child layout."
 99	examples=
100	'
101		<!--- Make sure that the `sidebar` value is provided for the parent layout --->
102		<cfsavecontent variable="categoriesSidebar">
103			<cfoutput>
104				<ul>
105					##includePartial(categories)##
106				</ul>
107			</cfoutput>
108		</cfsavecontent>
109		<cfset contentFor(sidebar=categoriesSidebar)>
110		
111		<!--- Include parent layout at `views/layout.cfm` --->
112		<cfoutput>
113			##includeLayout("/layout.cfm")##
114		</cfoutput>
115	'
116	categories="view-helper,miscellaneous" chapters="using-layouts" functions="usesLayout,renderPage">
117	<cfargument name="name" type="string" required="false" default="layout" hint="Name of the layout file to include.">
118	<cfscript>
119		arguments.partial = arguments.name;
120		StructDelete(arguments, "name");
121		arguments.$prependWithUnderscore = false;
122		return includePartial(argumentCollection=arguments);
123	</cfscript>
124</cffunction>
125
126<cffunction name="includePartial" returntype="string" access="public" output="false" hint="Includes the specified partial file in the view. Similar to using `cfinclude` but with the ability to cache the result and use Wheels-specific file look-up. By default, Wheels will look for the file in the current controller's view folder. To include a file relative from the base `views` folder, you can start the path supplied to `name` with a forward slash."
127	examples=
128	'
129		<cfoutput>##includePartial("login")##</cfoutput>
130		-> If we''re in the "admin" controller, Wheels will include the file "views/admin/_login.cfm".
131
132		<cfoutput>##includePartial(partial="misc/doc", cache=30)##</cfoutput>
133		-> If we''re in the "admin" controller, Wheels will include the file "views/admin/misc/_doc.cfm" and cache it for 30 minutes.
134
135		<cfoutput>##includePartial(partial="/shared/button")##</cfoutput>
136		-> Wheels will include the file "views/shared/_button.cfm".
137	'
138	categories="view-helper,miscellaneous" chapters="pages,partials" functions="renderPartial">
139	<cfargument name="partial" type="any" required="true" hint="See documentation for @renderPartial.">
140	<cfargument name="group" type="string" required="false" default="" hint="If passing a query result set for the `partial` argument, use this to specify the field to group the query by. A new query will be passed into the partial template for you to iterate over.">
141	<cfargument name="cache" type="any" required="false" default="" hint="See documentation for @renderPage.">
142	<cfargument name="layout" type="string" required="false" hint="See documentation for @renderPage.">
143	<cfargument name="spacer" type="string" required="false" hint="HTML or string to place between partials when called using a query.">
144	<cfargument name="dataFunction" type="any" required="false" hint="Name of controller function to load data from.">
145	<cfargument name="$prependWithUnderscore" type="boolean" required="false" default="true">
146	<cfset $args(name="includePartial", args=arguments)>
147	<cfreturn $includeOrRenderPartial(argumentCollection=$dollarify(arguments, "partial,group,cache,layout,spacer,dataFunction"))>
148</cffunction>
149
150<cffunction name="cycle" returntype="string" access="public" output="false" hint="Cycles through list values every time it is called."
151	examples=
152	'
153		<!--- Alternating table row colors --->
154		<table>
155			<thead>
156				<tr>
157					<th>Name</th>
158					<th>Phone</th>
159				</tr>
160			</thead>
161			<tbody>
162				<cfoutput query="employees">
163					<tr class="##cycle("odd,even")##">
164						<td>##employees.name##</td>
165						<td>##employees.phone##</td>
166					</tr>
167				</cfoutput>
168			</tbody>
169		</table>
170		
171		<!--- Alternating row colors and shrinking emphasis --->
172		<cfoutput query="employees" group="departmentId">
173			<div class="##cycle(values="even,odd", name="row")##">
174				<ul>
175					<cfoutput>
176						<cfset rank = cycle(values="president,vice-president,director,manager,specialist,intern", name="position")>
177						<li class="##rank##">##categories.categoryName##</li>
178						<cfset resetCycle("emphasis")>
179					</cfoutput>
180				</ul>
181			</div>
182		</cfoutput>
183	'
184	categories="view-helper,miscellaneous" functions="resetCycle">
185	<cfargument name="values" type="string" required="true" hint="List of values to cycle through.">
186	<cfargument name="name" type="string" required="false" default="default" hint="Name to give the cycle. Useful when you use multiple cycles on a page.">
187	<cfscript>
188		var loc = {};
189		if (!StructKeyExists(request.wheels, "cycle"))
190			request.wheels.cycle = {};
191		if (!StructKeyExists(request.wheels.cycle, arguments.name))
192		{
193			request.wheels.cycle[arguments.name] = ListGetAt(arguments.values, 1);
194		}
195		else
196		{
197			loc.foundAt = ListFindNoCase(arguments.values, request.wheels.cycle[arguments.name]);
198			if (loc.foundAt == ListLen(arguments.values))
199				loc.foundAt = 0;
200			request.wheels.cycle[arguments.name] = ListGetAt(arguments.values, loc.foundAt + 1);
201		}
202		loc.returnValue = request.wheels.cycle[arguments.name]; 
203	</cfscript>
204	<cfreturn loc.returnValue>
205</cffunction>
206
207<cffunction name="resetCycle" returntype="void" access="public" output="false" hint="Resets a cycle so that it starts from the first list value the next time it is called."
208	examples=
209	'
210		<!--- alternating row colors and shrinking emphasis --->
211		<cfoutput query="employees" group="departmentId">
212			<div class="##cycle(values="even,odd", name="row")##">
213				<ul>
214					<cfoutput>
215						<cfset rank = cycle(values="president,vice-president,director,manager,specialist,intern", name="position")>
216						<li class="##rank##">##categories.categoryName##</li>
217						<cfset resetCycle("emphasis")>
218					</cfoutput>
219				</ul>
220			</div>
221		</cfoutput>
222	'
223	categories="view-helper,miscellaneous" functions="cycle"
224	>
225	<cfargument name="name" type="string" required="false" default="default" hint="The name of the cycle to reset.">
226	<cfscript>
227		if (StructKeyExists(request.wheels, "cycle") && StructKeyExists(request.wheels.cycle, arguments.name))
228			StructDelete(request.wheels.cycle, arguments.name);
229	</cfscript>
230</cffunction>
231
232<cffunction name="$tag" returntype="string" access="public" output="false" hint="Creates a HTML tag with attributes.">
233	<cfargument name="name" type="string" required="true" hint="The name of the HTML tag.">
234	<cfargument name="attributes" type="struct" required="false" default="#StructNew()#" hint="The attributes and their values">
235	<cfargument name="close" type="boolean" required="false" default="false" hint="Whether or not to close the tag (self-close) or just end it with a bracket.">
236	<cfargument name="skip" type="string" required="false" default="" hint="List of attributes that should not be placed in the HTML tag.">
237	<cfargument name="skipStartingWith" type="string" required="false" default="" hint="If you want to skip attributes that start with a specific string you can specify it here.">
238	<cfscript>
239		var loc = {};
240		
241		// start the HTML tag and give it its name
242		loc.returnValue = "<" & arguments.name;
243		
244		// if named arguments are passed in we add these to the attributes argument instead so we can handle them all in the same code below
245		if (StructCount(arguments) gt 5)
246		{
247			for (loc.key in arguments)
248			{
249				if (!ListFindNoCase("name,attributes,close,skip,skipStartingWith", loc.key))
250				{
251					arguments.attributes[loc.key] = arguments[loc.key];
252				}
253			}
254		}
255		
256		// add the names of the attributes and their values to the output string with a space in between (class="something" name="somethingelse" etc)
257		// since the order of a struct can differ we sort the attributes in alphabetical order before placing them in the HTML tag (we could just place them in random order in the HTML but that would complicate testing for example)
258		loc.sortedKeys = ListSort(StructKeyList(arguments.attributes), "textnocase");
259		loc.iEnd = ListLen(loc.sortedKeys);
260
261		for (loc.i=1; loc.i lte loc.iEnd; loc.i++)
262		{
263			loc.key = ListGetAt(loc.sortedKeys, loc.i);
264			// place the attribute name and value in the string unless it should be skipped according to the arguments or if it's an internal argument (starting with a "$" sign)
265			if (!ListFindNoCase(arguments.skip, loc.key) && (!Len(arguments.skipStartingWith) || Left(loc.key, Len(arguments.skipStartingWith)) != arguments.skipStartingWith) && Left(loc.key, 1) != "$")
266			{
267				// replace boolean arguments for the disabled and readonly attributs with the key (if true) or skip putting it in the output altogether (if false)
268				if (ListFindNoCase("disabled,readonly", loc.key) and IsBoolean(arguments.attributes[loc.key]))
269				{
270					if (arguments.attributes[loc.key])
271					{
272						loc.returnValue &= $tagAttribute(loc.key, LCase(loc.key));
273					}
274				}
275				else
276				{
277					loc.returnValue &= $tagAttribute(loc.key, arguments.attributes[loc.key]);
278				}
279			}
280		}
281
282		// close the tag (usually done on self-closing tags like "img" for example) or just end it (for tags like "div" for example)
283		if (arguments.close)
284		{
285			loc.returnValue &= " />";
286		}
287		else
288		{
289			loc.returnValue &= ">";
290		}		
291	</cfscript>
292	<cfreturn loc.returnValue>
293</cffunction>
294
295<cffunction name="$tagAttribute" returntype="string" access="public" output="false">
296	<cfargument name="name" type="string" required="true">
297	<cfargument name="value" type="string" required="true">
298	<cfreturn ' #LCase(arguments.name)#="#arguments.value#"'>
299</cffunction>
300
301<cffunction name="$element" returntype="string" access="public" output="false">
302	<cfargument name="name" type="string" required="true">
303	<cfargument name="attributes" type="struct" required="false" default="#StructNew()#">
304	<cfargument name="content" type="string" required="false" default="">
305	<cfargument name="skip" type="string" required="false" default="">
306	<cfargument name="skipStartingWith" type="string" required="false" default="">
307	<cfscript>
308		var returnValue = "";
309		returnValue = arguments.content;
310		StructDelete(arguments, "content");
311		returnValue = $tag(argumentCollection=arguments) & returnValue & "</" & arguments.name & ">";
312	</cfscript>
313	<cfreturn returnValue>
314</cffunction>
315
316<cffunction name="$objectName" returntype="any" access="public" output="false">
317	<cfargument name="objectName" type="any" required="true">
318	<cfargument name="association" type="string" required="false" default="">
319	<cfargument name="position" type="string" required="false" default="">
320	<cfscript>
321		var loc = {};
322		loc.currentModelObject = false;
323		loc.hasManyAssociationCount = 0;
324		// combine our arguments
325		$combineArguments(args=arguments, combine="positions,position");
326		$combineArguments(args=arguments, combine="associations,association");
327		// only try to create the object name if we have a simple value
328		if (IsSimpleValue(arguments.objectName) && ListLen(arguments.associations))
329		{
330			for (loc.i = 1; loc.i lte ListLen(arguments.associations); loc.i++)
331			{
332				loc.association = ListGetAt(arguments.associations, loc.i);
333				loc.currentModelObject = $getObject(arguments.objectName);
334				arguments.objectName = arguments.objectName & "['" & loc.association & "']";
335				loc.expanded = loc.currentModelObject.$expandedAssociations(include=loc.association);
336				loc.expanded = loc.expanded[1];
337				// is this assocication a hasMany?
338				if (loc.expanded.type == "hasMany")
339				{
340					loc.hasManyAssociationCount++;
341					if (loc.hasManyAssociationCount gt ListLen(arguments.positions) && application.wheels.showErrorInformation)
342						$throw(type="Wheels.InvalidArgument", message="You passed the hasMany association of `#loc.association#` but did not provide a corresponding position.");
343					arguments.objectName = arguments.objectName & "[" & ListGetAt(arguments.positions, loc.hasManyAssociationCount) & "]";
344				}
345			}
346		}
347	</cfscript>
348	<cfreturn arguments.objectName>
349</cffunction>
350
351<cffunction name="$tagId" returntype="string" access="public" output="false">
352	<cfargument name="objectName" type="any" required="true">
353	<cfargument name="property" type="string" required="true">
354	<cfargument name="valueToAppend" type="string" default="">
355	<cfscript>
356		var loc = {};
357		if (IsSimpleValue(arguments.objectName))
358		{
359			// form element for object(s)
360			loc.returnValue = ListLast(arguments.objectName, ".");
361			if (Find("[", loc.returnValue))
362				loc.returnValue = $swapArrayPositionsForIds(objectName=loc.returnValue);
363			if (Find("($", arguments.property))
364				arguments.property = ReplaceList(arguments.property, "($,)", "-,");
365			if (Find("[", arguments.property))
366				loc.returnValue = REReplace(REReplace(loc.returnValue & arguments.property, "[,\[]", "-", "all"), "[""'\]]", "", "all");
367			else
368				loc.returnValue = REReplace(REReplace(loc.returnValue & "-" & arguments.property, "[,\[]", "-", "all"), "[""'\]]", "", "all");
369		}
370		else
371		{
372			loc.returnValue = ReplaceList(arguments.property, "[,($,],',"",)", "-,-,");
373		}
374		if (Len(arguments.valueToAppend))
375			loc.returnValue = loc.returnValue & "-" & arguments.valueToAppend;
376	</cfscript>
377	<cfreturn REReplace(loc.returnValue, "-+", "-", "all")>
378</cffunction>
379
380<cffunction name="$tagName" returntype="string" access="public" output="false">
381	<cfargument name="objectName" type="any" required="true">
382	<cfargument name="property" type="string" required="true">
383	<cfscript>
384		var loc = {};
385		if (IsSimpleValue(arguments.objectName))
386		{
387			loc.returnValue = ListLast(arguments.objectName, ".");
388			if (Find("[", loc.returnValue))
389				loc.returnValue = $swapArrayPositionsForIds(objectName=loc.returnValue);
390			if (Find("[", arguments.property))
391				loc.returnValue = ReplaceList(loc.returnValue & arguments.property, "',""", "");
392			else
393				loc.returnValue = ReplaceList(loc.returnValue & "[" & arguments.property & "]", "',""", "");
394		}
395		else
396		{
397			loc.returnValue = arguments.property;
398		}
399	</cfscript>
400	<cfreturn loc.returnValue>
401</cffunction>
402
403<cffunction name="$swapArrayPositionsForIds" returntype="string" access="public" output="false">
404	<cfargument name="objectName" type="any" required="true" />
405	<cfscript>
406		var loc = {};
407		loc.returnValue = arguments.objectName;
408		
409		// we could have multiple nested arrays so we need to traverse the objectName to find where we have array positions and
410		// swap all of the out for object ids
411		loc.array = ListToArray(ReplaceList(loc.returnValue, "],'", ""), "[", true);
412		loc.iEnd = ArrayLen(loc.array);
413		for (loc.i = 1; loc.i lte loc.iEnd; loc.i++)
414		{
415			if (REFind("\d", loc.array[loc.i])) // if we find a digit, we need to replace it with an id
416			{
417				// build our object reference
418				loc.objectReference = "";
419				for (loc.j = 1; loc.j lte loc.i; loc.j++)
420					loc.objectReference = ListAppend(loc.objectReference, ListGetAt(arguments.objectName, loc.j, "["), "[");
421				loc.returnValue = ListSetAt(loc.returnValue, loc.i, $getObject(loc.objectReference).key($returnTickCountWhenNew=true) & "]", "[");
422			}
423		}
424	</cfscript>
425	<cfreturn loc.returnValue />
426</cffunction>
427
428<cffunction name="$addToJavaScriptAttribute" returntype="string" access="public" output="false">
429	<cfargument name="name" type="string" required="true">
430	<cfargument name="content" type="string" required="true">
431	<cfargument name="attributes" type="struct" required="true">
432	<cfscript>
433		var loc = {};
434		if (StructKeyExists(arguments.attributes, arguments.name))
435		{
436			loc.returnValue = arguments.attributes[arguments.name];
437			if (Right(loc.returnValue, 1) != ";")
438				loc.returnValue = loc.returnValue & ";";
439			loc.returnValue = loc.returnValue & arguments.content;
440		}
441		else
442		{
443			loc.returnValue = arguments.content;
444		}
445	</cfscript>
446	<cfreturn loc.returnValue>
447</cffunction>
448
449<cffunction name="$getObject" returntype="any" access="public" output="false" hint="Returns the object referenced by the variable name passed in. If the scope is included it gets it from there, otherwise it gets it from the variables scope.">
450	<cfargument name="objectName" type="string" required="true">
451	<cfscript>
452		var loc = {};
453		loc.returnValue = "";
454		
455		try
456		{
457			if (Find(".", arguments.objectName) or Find("[", arguments.objectName)) // we can't directly invoke objects in structure or arrays of objects so we must evaluate
458				loc.returnValue = Evaluate(arguments.objectName);
459			else
460				loc.returnValue = variables[arguments.objectName];
461		}
462		catch (Any e)
463		{
464			if (application.wheels.showErrorInformation)
465				$throw(type="Wheels.ObjectNotFound", message="Wheels tried to find the model object `#arguments.objectName#` for the form helper, but it does not exist.");
466			else
467				$throw(argumentCollection=e);
468		}	
469	</cfscript>
470	<cfreturn loc.returnValue>
471</cffunction>