URL rewriter crashes knockout.js templates

Vote:
 

The URL rewriter seem to destroy my template markup. The comment style if's are chopped off. Is it possible to instruct the rewriter to not mess with certain elements?

<script type="text/html" id="goal-template">
			<li class="event goal" data-bind="css: {hometeam: hometeam, awayteam: !hometeam}">
				<time data-bind="text: game_time.as_string"></time>
				Mål
				<span data-bind="template: {name: 'team-link-template', data: participants[0].getPlayer().team}"></span>
				<span data-bind="template: {name: 'player-link-template', data: participants[0]}"></span>

				<!-- ko if: participants[1] -->
					(passning <span data-bind="template: {name: 'player-link-template', data: participants[1]}"></span>)
				<!-- /ko -->
			</li>
</script>

    

#69558
Mar 27, 2013 13:25
Vote:
 

http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=415 - OK, so creating your own rewriter seems to be the only option. Would be nice to have some sort of element skiplist for the built-in rewriter.

#69559
Edited, Mar 27, 2013 13:31
Vote:
 

Hi Johan,

The link above was dead. Any chance of digging it back up???

How did the rewriter that you wrote look in the end?

Andrew.

#86594
May 26, 2014 11:47
Vote:
 

I didn't solve it through a Rewriter in the end. Instead I just added a folder in project and in it a default.aspx that just contains <%= GetContent %> (and some small info inside HTML-comments) and this example code behind:

public partial class Default : System.Web.UI.Page
{
	protected string GetContent()
	{
		string html = ReadRemoteUrl("http://yoursite.com/some-epi-page-url/");
		return html.Replace("<div data-knockout-include=\"true\"></div>", this.IncludeFile("/gui/knockout-template.html"));
	}

	protected string IncludeFile(string path)
	{
		string content;
		string filename = Server.MapPath(path);

		using (StreamReader reader = File.OpenText(filename))
		{
			content = reader.ReadToEnd();
		}

		return content;
	}
}

Inheriting System.Web.UI.Page will make EPi leave it alone and visitors can reach it through /vs-folder-name/ URL. You could also use a regular HttpHandler. I didn't choose a handler because it required Web.Config additions.

#86601
May 26, 2014 13:37
Vote:
 

Hi all,

For those that find this, you can implement a custom URL Rewrite Provider as alluded to by Johan in his original post.

Here's what I used:

    public class FriendlyUrlRewriteProvider : EPiServer.Web.FriendlyUrlRewriteProvider
    {
        public override EPiServer.Web.HtmlRewriteToExternal GetHtmlRewriter()
        {
            return new FriendlyHtmlRewriteToExternal(UrlRewriteProvider.RebaseKind);
        }
    }

    public class FriendlyHtmlRewriteToExternal : EPiServer.Web.FriendlyHtmlRewriteToExternal
    {
        private static Regex MisformattedCommentRegex = new Regex(@"^(\s*)--", RegexOptions.Compiled);

        public FriendlyHtmlRewriteToExternal(EPiServer.UrlBuilder.RebaseKind rebaseKind) : base(rebaseKind)
        {
        }

        protected override void OnHtmlRewriteInit(HtmlRewriteEventArgs e)
        {
            if (e.RewritePipe != null)
            {
                e.RewritePipe.HtmlRewriteName += RewritePipe_HtmlRewriteName;
                e.RewritePipe.HtmlRewriteValue += RewritePipe_HtmlRewriteValue;
            }
            base.OnHtmlRewriteInit(e);
        }

        void RewritePipe_HtmlRewriteName(object sender, HtmlRewriteEventArgs e)
        {
            if (e.NodeType == System.Xml.XmlNodeType.Attribute && e.ElementType == HtmlRewritePipe.ElementTypes.SCRIPT)
            {
                var value = e.Value;
                if (StringComparer.InvariantCultureIgnoreCase.Equals(value, "text/html"))
                {
                    e.IsInsidePreventUrlElement = true;
                }
            }
        }

        void RewritePipe_HtmlRewriteValue(object sender, HtmlRewriteEventArgs e)
        {
            if (e.ElementType == HtmlRewritePipe.ElementTypes.SCRIPT && e.IsInsidePreventUrlElement && e.NodeType == System.Xml.XmlNodeType.CDATA)
            {
                var value = e.Value;
                if (MisformattedCommentRegex.IsMatch(value))
                {
                    e.ValueBuilder.Length = 0;
                    e.ValueBuilder.Append(MisformattedCommentRegex.Replace(value, "$1<!--"));
                }
            }
        }
    }


And it was plugged into the web.config within the urlRewrite node:

  <urlRewrite defaultProvider="MyFriendlyUrlRewriteProvider">
    <providers>
      <add description="EPiServer standard Friendly URL rewriter with comment ignoring" name="MyFriendlyUrlRewriteProvider"
        type="MyNamespace.FriendlyUrlRewriteProvider, MyAssembly" />
      <add description="EPiServer standard Friendly URL rewriter" name="EPiServerFriendlyUrlRewriteProvider"
        type="EPiServer.Web.FriendlyUrlRewriteProvider,EPiServer" />
      <add description="EPiServer identity URL rewriter" name="EPiServerIdentityUrlRewriteProvider"
        type="EPiServer.Web.IdentityUrlRewriteProvider,EPiServer" />
      <add description="EPiServer bypass URL rewriter" name="EPiServerNullUrlRewriteProvider"
        type="EPiServer.Web.NullUrlRewriteProvider,EPiServer" />
    </providers>
  </urlRewrite>

Hope that helps someone out there!

#86629
May 27, 2014 9:31
Vote:
 

Great! That should work with EPi 7 and Web Forms too. I'm guessing there's no similiar issue in when using MVC.

#86632
May 27, 2014 9:47
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.