Index: farcry_core/packages/types/_dmnavigation/edit.cfm
===================================================================
--- farcry_core/packages/types/_dmnavigation/edit.cfm	(.../farcry-2.3)	(revision 8)
+++ farcry_core/packages/types/_dmnavigation/edit.cfm	(.../fuchanges_0-1)	(revision 8)
@@ -81,34 +81,9 @@
 		<!--- get current fu --->
 		<cfset fuUrl = application.factory.oFU.getFU(objectid=stObj.objectid)>
 		
-		<!--- check for suffix --->
-		<cfif listLen(application.config.fusettings.suffix,"/") gt 0 and not listContains(fuUrl,"objectid")>
-			<cfset fuLen = listLen(fuURL,"/") - listLen(application.config.fusettings.suffix,"/")>
-		<cfelse>
-			<cfset fuLen = listLen(fuURL,"/")>
-		</cfif>
-		
 		<!--- check if new object --->
-		<cfif listContains(fuUrl,"objectid")>
-			<!--- get ancestors --->
-			<cfset qAncestors = request.factory.oTree.getAncestors(objectid=stobj.objectid,bIncludeSelf=false)>
-			<!--- remove root & home --->
-			<cfquery dbtype="query" name="qCrumb">
-				SELECT objectName FROM qAncestors
-				WHERE nLevel >= 2
-				ORDER BY nLevel
-			</cfquery>				
-			<!--- join titles together --->
-			<cfset breadCrumb = valueList(qCrumb.objectname)>
-			<!--- change delimiter --->
-			<cfset breadCrumb = listChangeDelims(breadCrumb,"/",",")>				
-			<!--- append new title --->
-			<cfset breadCrumb = listAppend(breadCrumb,form.title,"/")>				
-			
-			<!--- set new fu --->
-			<cfset fuUrl = application.config.fusettings.urlpattern&breadcrumb&application.config.fusettings.suffix>
-			<!--- set fu --->
-			<cfset application.factory.oFU.setFU(objectid=stobj.objectid,alias=lcase(fuUrl))>
+		<cfif not application.factory.oFU.hasFU(objectid=stObj.objectID)>
+         <cfset application.factory.oFU.createAndSetFUAlias(objectid=stObj.objectID) />
 		<cfelse>
 			<!--- delete current fu --->
 			<cfset application.factory.oFU.deleteFu(fuUrl)>
@@ -120,37 +95,17 @@
 					<cfset descfuUrl = application.factory.oFU.getFU(objectid=qGetDescendants.objectid)>
 					<!--- check if descendants have fus set --->
 					<cfif listContains(descfuUrl,"objectid")>
-						<!--- get ancestors --->
-						<cfset qAncestors = request.factory.oTree.getAncestors(objectid=qGetDescendants.objectid,bIncludeSelf=true)>
-						<!--- remove root & home --->
-						<cfquery dbtype="query" name="qCrumb">
-							SELECT objectName FROM qAncestors
-							WHERE nLevel >= 2
-							ORDER BY nLevel
-						</cfquery>
-						<!--- join titles together --->
-						<cfset breadCrumb = valueList(qCrumb.objectname)>
-						<!--- change delimiter --->
-						<cfset breadCrumb = listChangeDelims(breadCrumb,"/",",")>
-						<!--- set new fu for descendant --->
-						<cfset newFu = application.config.fusettings.urlpattern&breadcrumb&application.config.fusettings.suffix>
 						<!--- set fu for descendant --->
-						<cfset application.factory.oFU.setFU(objectid=qGetDescendants.objectid,alias=lcase(newFu))>
+						<cfset application.factory.oFU.createAndSetFUAlias(objectid=qGetDescendants.objectid)>
 					<cfelse>
 						<!--- delete current fu for descendant --->
 						<cfset application.factory.oFU.deleteFu(descfuUrl)>
-						<!--- work out new fu for descendant  --->
-						<cfset newfu = listSetAt(descfuUrl,fuLen,form.title,"/")>
-						<!--- set new fu  for descendant --->
-						<cfset application.factory.oFU.setFu(objectid=qGetDescendants.objectid,alias=lcase(newfu))>
+						<cfset application.factory.oFU.createAndSetFUAlias(objectid=qGetDescendants.objectid)>
 					</cfif>
 				</cfloop>
-			</cfif>
-			
-			<!--- work out new fu for actual object--->
-			<cfset newfu = listSetAt(fuUrl,fuLen,form.title,"/")>
+			</cfif>		
 			<!--- set fu for actual object --->
-			<cfset application.factory.oFU.setFU(objectid=stobj.objectid,alias=lcase(newfu))>
+			<cfset application.factory.oFU.createAndSetFUAlias(objectid=stobj.objectid)>
 		</cfif> 
 	</cfif>
 	
@@ -215,6 +170,10 @@
 							<td nowrap><span class="FormLabel">#application.adminBundle[session.dmProfile.locale].navAliases#</span></td>
 							<td nowrap><input type="text" name="lNavIDAlias" value="#stObj.lNavIDAlias#" class="FormTextBox"></td>
 						</tr>
+						<tr valign="top">
+							<td nowrap><span class="FormLabel">Friendly URL:</span></td>
+							<td nowrap><input type="text" name="fu" value="#stObj.fu#" class="FormTextBox"></td>
+						</tr>
 						</table>
 						</display:OpenLayer>
 					</div>
Index: farcry_core/packages/types/dmNavigation.cfc
===================================================================
--- farcry_core/packages/types/dmNavigation.cfc	(.../farcry-2.3)	(revision 8)
+++ farcry_core/packages/types/dmNavigation.cfc	(.../fuchanges_0-1)	(revision 8)
@@ -32,6 +32,7 @@
 <cfproperty name="lNavIDAlias" type="string" hint="A Nav alias provides a human interpretable link to this navigation node.  Each Nav alias is set up as key in the structure application.navalias.<i>aliasname</i> with a value equal to the navigation node's UUID." required="no" default="">
 <cfproperty name="options" type="string" hint="No idea what this is for." required="no" default="">
 <cfproperty name="status" type="string" hint="Status of the node (draft, pending, approved)." required="yes" default="draft">
+<cfproperty name="fu" type="string" hint="Friendly URL for this node." required="no" default="">
 
 <!------------------------------------------------------------------------
 object methods 
Index: farcry_core/packages/farcry/fu.cfc
===================================================================
--- farcry_core/packages/farcry/fu.cfc	(.../farcry-2.3)	(revision 8)
+++ farcry_core/packages/farcry/fu.cfc	(.../fuchanges_0-1)	(revision 8)
@@ -144,22 +144,34 @@
 		<cfset application.FU.mappings = stTemp>
 	</cffunction>
 
-	<cffunction name="createFUAlias" access="public" returntype="string" hint="Creates the FU Alias for a given objectid">
+	<cffunction name="createFUAlias" access="public" returntype="string" hint="Creates the FU Alias for a given objectid" output="true">
 		<cfargument name="objectid" required="Yes">
 		
 		<cfset var qCrumb = "">
 		<cfset var breadCrumb = "">
 		<cfset var qAncestors = request.factory.oTree.getAncestors(objectid=arguments.objectid,bIncludeSelf=true)>
-		
+		<cfset var oNav = createObject("component",application.types.dmNavigation.typepath)>
+		<cfset var i = 0>
 		<!--- remove root & home --->
 		<cfquery dbtype="query" name="qCrumb">
-			SELECT objectName FROM qAncestors
+			SELECT objectName, objectID FROM qAncestors
 			WHERE nLevel >= 2
 			ORDER BY nLevel
 		</cfquery>
+		<cfif qCrumb.recordCount eq 0>
+		   <cfreturn "" />
+		</cfif>
 		<cfscript>
-			// join titles together 
-			breadCrumb = lcase(valueList(qCrumb.objectname));
+   		// collect fu labels if the object has any, otherwise just use objectname
+   		for(i=1; i lte qCrumb.recordCount; i=i+1) {
+   		   stObj = oNav.getData(objectid=qCrumb.objectID[i]);
+   		   if ( StructKeyExists(stObj,"fu") and len(trim(stObj.fu)) ) {
+   		      breadcrumb = listAppend(breadcrumb,lcase(stObj.fu));
+   		   }
+   		   else {
+   		      breadcrumb = listAppend(breadcrumb,lcase(qCrumb.objectname[i]));
+   		   }
+   		}
 			// change delimiter 
 			breadCrumb = listChangeDelims(breadCrumb,"/",",");
 			// remove spaces 
@@ -170,6 +182,20 @@
 	<cfreturn breadcrumb>	
 	</cffunction>	
 	
+	<cffunction name="createAndSetFUAlias" access="public" returntype="string" hint="Creates and sets an the FU mapping for a given dmNavigation object. Returns the generated friendly URL." output="true">
+	   <cfargument name="objectid" required="true" hint="The objectid of the dmNavigation node" />
+      <cfset var breadCrumb = "">
+      <cfif arguments.objectid eq application.navid.home>
+         <cfset breadcrumb = application.config.fusettings.urlpattern />
+      <cfelse>
+         <cfset breadcrumb = createFUAlias(objectid=arguments.objectid) />
+      </cfif>
+      <cfif breadCrumb neq "">
+			<cfset setFU(objectid=arguments.objectid,alias=breadcrumb) />
+      </cfif>
+      <cfoutput><br>Setting FU for objectid #arguments.objectid# to #breadcrumb#<br></cfoutput>
+      <cfreturn breadCrumb />
+	</cffunction>
 	
 	<cffunction name="createAll" access="public" returntype="boolean" hint="Deletes old mappings and creates new entries for entire tree, and writes the map file to disk" output="yes">
 		
@@ -178,7 +204,11 @@
 		<cfset var qAncestors = "">
 		<cfset var qCrumb = "">
 		<cfset var breadCrumb = "">
-				
+		<cfset var oNav = createObject("component",application.types.dmNavigation.typepath)>
+		<cfset var i = 0>
+
+	   <cfoutput><br>createAll<br></cfoutput>
+
 		<!--- remove existing fu's --->
 		<cfset deleteALL()>
 		<!--- set error template --->		
@@ -187,29 +217,13 @@
 		<cfset setURLVar("nav")>
 		<!--- loop over nav tree and create friendly urls --->
 		<cfloop query="qNav">
-			<!--- get ancestors of object --->
-			<cfset qAncestors = request.factory.oTree.getAncestors(objectid=objectid,bIncludeSelf=true)>
-			<!--- remove root & home --->
-			<cfquery dbtype="query" name="qCrumb">
-				SELECT objectName FROM qAncestors
-				WHERE nLevel >= 2
-				ORDER BY nLevel
-			</cfquery>
-			<cfif val(qCrumb.recordcount)>
-				<!--- join titles together --->
-				<cfset breadCrumb = lcase(valueList(qCrumb.objectname))>
-				<!--- change delimiter --->
-				<cfset breadCrumb = listChangeDelims(breadCrumb,"/",",")>
-				<!--- remove spaces --->
-				<cfset breadCrumb = replace(breadCrumb,' ','-',"all") & application.config.fusettings.suffix>
-				<!--- create fu --->
-				<cfset setFU(objectid=objectid,alias=application.config.fusettings.urlpattern&breadcrumb)>
-			</cfif>
+		   <cfoutput>creating FU for #qNav.objectid#</cfoutput>
+         <cfset createAndSetFUAlias(objectid=qNav.objectid) />
 		</cfloop>
 		<!--- create fu for home--->
-		<cfset setFU(objectid=application.navid.home,alias=application.config.fusettings.urlpattern)>
-		<cfset updateAppScope()>
-		<cfreturn true>
+		<cfset createAndSetFUAlias(objectid=application.navid.home) />
+		<cfset updateAppScope() />
+		<cfreturn true />
 	</cffunction>
 	
 	<cffunction name="setFU" access="public" returntype="string" hint="Sets an fu" output="No">
@@ -261,5 +275,12 @@
 			return fuURL;
 		</cfscript>
 	</cffunction>
+	
+	<cffunction name="hasFU" access="public" returntype="boolean" hint="Returns whether an FU has been set for the given objectid">
+	   <cfargument name="objectid" required="yes" hint="Objectid of object" />
+	   <cfset var fu = getFU(objectid=arguments.objectid) />
+	   <!--- if getFU() returned a string containing "objectid" then we should return false --->
+	   <cfreturn not listContains(fu,"objectid") />
+	</cffunction>
 
 </cfcomponent>
\ No newline at end of file
