written by John Allen, 04. December 2011
How to implement unique filenames across a project - everything you need to know for a robust approach. (As I'm busy destroying fixing our house with various DIY projects it's going to be a short and sweet post.)
Only works in smart tree mode.
Doesn't work with direct edit of headline enabled (the cache of the page isn't cleared / updated).
The logic is fairly straightforward if you look at the template code.
There are two checks, one for filename changes and one for headline changes and the filename is then updated accordingly. A mandatory field is used to stop the page from being released until a unique filename has been set (the user must supply one if a clash has occured).
We need some extra fields in our content class:
Here is the extra code we need in our template:
<!IoRangeRedDotEditOnly> <script type="text/javascript"> head(function () { var h1headline = $('h1').html(); var reload = false; // If user updates headline (or creates new page) if (("<%Unique_Filename%>" != "Disabled") && ("<%!! Escape:HtmlEncode(<%hdlHeadline%>) !!%>" != "<%!! Escape:HtmlEncode(<%stfPreviousHeadline%>) !!%>")) { // parse headline var parsedHeadline = h1headline.toLowerCase().replace(/(\s|\.|_|"|')+/g, "-"); var parsedHeadline = parsedHeadline.replace(/(\?)+/g, ""); if (IsUniqueFilenameTest("<%infPageGuid%>", parsedHeadline )) { SetFilename("<%infPageGuid%>", parsedHeadline); SetElement("<%infPageGuid%>", "Unique_Filename", "Unlocked"); SetElement("<%infPageGuid%>", "stfPreviousHeadline", h1headline); SetElement("<%infPageGuid%>", "stfPreviousFilename", Filename("<%infPageGuid%>")); reload = true; } else { if ("<%!! Escape:HtmlEncode(<%stfPreviousFilename%>) !!%>" != "" || "<%Unique_Filename%>" != "" || Filename("<%infPageGuid%>") != "") { // Stop the updated filename check from firing SetFilename("<%infPageGuid%>", ""); SetElement("<%infPageGuid%>", "stfPreviousFilename", ""); // set flag to block page release. SetElement("<%infPageGuid%>", "Unique_Filename", ""); reload = true; } } } // If user updates filename if (("<%Unique_Filename%>" != "Disabled")) { var filename = Filename("<%infPageGuid%>"); if (filename != "<%stfPreviousFilename%>") { if (IsUniqueFilename("<%infPageGuid%>") && filename != "") { SetElement("<%infPageGuid%>", "stfPreviousHeadline", h1headline ); SetElement("<%infPageGuid%>", "stfPreviousFilename", filename); SetElement("<%infPageGuid%>", "Unique_Filename", "Unlocked"); reload = true; } else { if ("<%Unique_Filename%>" != "") { // set flag to block page release. SetElement("<%infPageGuid%>", "Unique_Filename", ""); reload = true; } } } } if (reload) { ClearCache("<%infPageGuid%>"); //location.reload(); } }); </script> <!/IoRangeRedDotEditOnly>
You will also need to include the following somewhere:
function ExecuteRql(rqlCommand) { var result = ""; $.each(rqlCommand, function (commandName, commandParameters) { $.ajax({ type: "POST", async: false, contentType: "application/json; charset=utf-8", data: JSON.stringify(commandParameters), url: "/services/services.asmx/" + commandName, dataType: "json", success: function (response) { result = response.d; }, error: function (response) { }, complete: function (response) { } }); }); return result; } function DeletePage(pageGuid) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid }; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", data: JSON.stringify(params), url: "/services/services.asmx/Delete", dataType: "json" }); } function Filename(pageGuid) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid }; var rqlCommand = { "Filename": params }; return ExecuteRql(rqlCommand); } function SetFilename(pageGuid, filename) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid, "filename": filename }; var rqlCommand = { "SetFilename": params }; return ExecuteRql(rqlCommand); } function IsUniqueFilename(pageGuid) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid }; var rqlCommand = { "IsUniqueFilename": params }; return ExecuteRql(rqlCommand); } function IsUniqueFilenameTest(pageGuid, filename) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid, "filename": filename }; var rqlCommand = { "IsUniqueFilenameTest": params }; return ExecuteRql(rqlCommand); } function SetElement(pageGuid, elementName, elementValue) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid, "elementName": elementName, "elementValue": elementValue }; var rqlCommand = { "SetElement": params }; return ExecuteRql(rqlCommand); } function ClearCache(pageGuid) { var params = { "loginGuid": "<%infLoginGuid%>", "sessionKey": "<%infSessionKey%>", "pageGuid": pageGuid }; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", data: JSON.stringify(params), url: "/services/services.asmx/ClearCache", dataType: "json" }); }
Last but not least you will need the *updated* RustyLogic RedDotNet library including the .asmx (which I will upload to solutions exchange when I get a chance and post a link here).
A very dry post I'm afraid but I hope still useful :)
Ta,
John
Source: RedDot SEO (Part 2)
© copyright 2011 by John Allen