volume_up

A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

volume_up

A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

URL rewriter crashes knockout.js templates

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

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

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

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

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