Even More Elegant URLs in MCMS + The Mac issue.

Stefan Gossner is the resource for MCMS.

Update :: Stefan has posted a new entry about this. Solving the "ugly" URL issue for Mac clients

He has a couple of posts about ugly urls :

A more elegant solution to avoid ugly URL's with MCMS

How to avoid the ugly GUID based URL's

I've dealt with similar problems and I based it on these postings.

In addition to ugly, there is an issue with IE on Mac. When you change the form action in script in the manner that MCMS does (also in Stefan's work-around), you get very strange behavior, anything you click causes a postback.

I haven't drilled down on the exact details of the bug, but it is IE on Mac, probably version 5.5.
(Change the form action with javascript that is inside the form tag)

The code I've posted for OnPreRequestHandlerExecute is a little different; I Rewrite the path and I don't go digging for the __CMS_Page script block in OnInit.

I want to get rid of the script block, not modify it. I could do this the same way as Stefan by calling  x.RegisterClientScriptBlock("__CMS_Page","") so that the key is used, but I like the idea of filtering it out instead.

In my base class (used for all pages) I override RegisterClientScriptBlock and do nothing if the key is __CMS_Page. If you don't have a common base page, you can try the register a blank script approach.

Nota Bene:
I figured this out on a site that is no longer using MCMS, so I proofed and tested it using the woodgrovenet sample site
I have not yet figured out how to make this work with multiple root channels, it gives me a error about mapping to annother application.

public void OnPreRequestHandlerExecute(object o, EventArgs e)

{

      HttpContext ctx = ((HttpApplication)o).Context;

      IHttpHandler handler = ctx.Handler;

 

      // lets correct the ugly URLs when switching between update and published mode

      Posting thisPosting = CmsHttpContext.Current.Posting;

      PublishingMode currentMode = CmsHttpContext.Current.Mode;

 

      if (thisPosting != null && currentMode == PublishingMode.Published)

      {

            if ( ctx.Request.QueryString["NRORIGINALURL"] != null &&

                  ctx.Request.QueryString["NRORIGINALURL"].StartsWith("/NR/exeres") ) // oh so ugly

            {

                  if ( !thisPosting.Url.StartsWith("/NR/exeres") )

                        ctx.Response.Redirect (thisPosting.Url);

            }

      }

 

      // to correct the ugly URL problem for normal postbacks we have to register an eventhandler for the

      // Init event of the page object. This handler then can register a better client script block as the one in

      // the console code

     

      //Here it gets different...

      if(thisPosting != null)

      {

            //Dig the QueryString out of the UrlInner

            string urlInner = thisPosting.UrlInner;

            string postingQS = "";

            if(urlInner.IndexOf("?")>-1)

            {

                  postingQS = urlInner.Split('?')[1];

            }

            //Rewrite the path so that the webform (form tag) will have the posting's url

            Context.RewritePath(thisPosting.UrlModePublished,"",postingQS);

      }

     

}

In your base class:

public override void RegisterClientScriptBlock(string key, string script)

{

      //Response.Write(key + "<HR>");

      if(key!="__CMS_Page")base.RegisterClientScriptBlock (key, script);

}

 

 

 

5 Comments

  • This looks good. But you don't have to pass the query string in published mode.

    The caveat with your code: on IE you will no longer be able to switch to edit mode as you removed the script block. So you should add some code to check for the browser version.

    In addition I would suggest to bind your overriden RegisterClientScriptBlock method in the HttpHandler as I did - this would avoid the need to have a &quot;master page&quot;.



    Cheers,

    Stefan.

  • Thanks Stefan.



    The stuff with the query string is for those just in case situations where the posting is given a query string posting.htm?aParamMightHappen=1 and you want that qs to be persisted during postback.



    Dealing with the script block in the handler is better encapsulation, but I only realized how to do it as I wrote...I will try it.

    The (small) expense of walking the control tree is probably a good trade off.







  • Just tested your approach.

    If the published URL has a different scope but then you get the following exception:



    Server Error in '/CmsHtmlPhTemplate' Application.

    --------------------------------------------------------------------------------



    The virtual path '/Stefan/TestCh/htmlpage.htm' maps to another application, which is not allowed.





    I will create a more general solution which works in all cases. Give me some minutes...

  • Yes, thats the same error we had when there were multiple root channels.



    Cool

  • I have a solution.

    Before posting I would like you to test it (I don't have a Mac).

    could you please send me a mail to webmaster@stefan-gossner.de so that I can send you the code?



    Thanks,

    Stefan.

Comments have been disabled for this content.