Sunday, 4 December 2011

RedDot SEO (Part 2)

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.)

Caveats:
Only works in smart tree mode.
Doesn't work with direct edit of headline enabled (the cache of the page isn't cleared  / updated).
How does it work?
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:
  • stfPreviousFilename (stf string)
  • stfPreviousHeadline (stf string)
  • Unique_Filename (stf string) (Mandatory field)
  • infPageGuid (Guid of page)

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


2 comments:

  1. I do have one question. Where exactly do you add that second bunch of code? Thanks in advance.

    seo reseller

    ReplyDelete
    Replies
    1. Just make sure it's in your template somewhere.

      Delete