URL Speed Bump using Orchard Workflows

Topics: Administration, Customizing Orchard, Writing modules
Aug 28, 2014 at 12:02 AM
I need to create a speed bump that issues a warning whenever a user clicks on a url on the site. My initial idea was to create a workflow that checks the content of any content item upon creation or submission and add the speed bump to the url then but I am having trouble creating custom workflow activities that would allow for such. How should I utilize the workflows module to create a speed bump? The speed bump should be a customizable content item so each tenant site can have their own custom speed bump page. The page should then redirect the user to the original url after 5 seconds. It would be nice if the speedbump could be added to all external urls and ignored for all urls that link to other pages on the same domain. Please help.
Aug 29, 2014 at 3:37 AM
Edited Aug 29, 2014 at 5:45 AM
What is a speed bump? On the one hand you say it's a content item, but on the other hand you say that you want to add the speed bump to the URL. Could you elaborate a little more?
Aug 29, 2014 at 4:37 AM
I apologize, a speed bump is what I was told the warning page that pops up when a user tries to leave a site is called. Basically what I'm asking for is a way in Orchard to make all URLs that point to a website on a separate domain first go to a page that issues a warning we will not be held liable for the user visiting this site and then take them to the site the URL actually points to. I was able to do this by editing the TinyMce module to include an option for a "speedbump" when the URL is inserted into the body of a page. If the user selects to include a speed bump then I wrote some code that adds an onClick attribute to the link (just like the target attribute that gets added when you select to have the link open in a new window) which has a value of some javascript code. The code prevents the default action of the URL then links the user to a page on the site called speed bump which I created which is really just a page content type with some javascript code imbedded that will grab the url value in the query string, wait five seconds and then link to the url in the query string which is the url provided when the link was created. This allows a user to style the speed bump page however they like and all links that were inserted with a speed bump first go to the speed bump page passing in the inserted link's url in the query string and then that speed bump page directs the user to the intended website. This works but there are a few problems including the need to recode this every time the TinyMce module is updated. I believe a better option would be to create a workflow that starts whenever a user clicks on a link the workflow could then redirect the user to a custom page known as the speed bump which is just a page content type that has a warning on it about leaving the site, wait 5 seconds and then redirect the user again to the url of the link.

So basically I need a way to create a customizable page that will be shown to the user whenever they click on a link that would direct them to a website on another domain.

Another issue is in the way I am currently creating a speed bump a third party could inject a url into the query string and send the user to a malicious website instead of the one they were meaning to go to.

Sorry if this doesn't make much sense. I've been banging my head on this for quite some time and can't figure it out. I really appreciate any help you can give me.
Aug 29, 2014 at 6:02 AM
Ah right, I see now. So how about this:
  1. Write a javascript file that unobtrusively binds the "click" event handler for all <a> elements on the page. The click event handler will inspect the target URL, and if it detects that the target is outside of the current domain, you prevent the default navigation action (e.preventDefault()) and redirect to your bump speed page instead (including the target URL using a querystring parameter).
  2. Your script will have to know the URL of the bump speed page - this could be a site setting you create (which could be as simple as attaching a TextField to the Site content type if you like, or event better - a ContentPickerField). To make the URL to this page available to your script, you could render an HTML5 data attribute on the body tag for example. Your script would know to look for this data attribute.
As far as I can see, no need for a workflow.

Hope this helps.
Marked as answer by emeraldarcher on 8/29/2014 at 7:58 AM
Aug 29, 2014 at 4:58 PM
Thank you this helps immensly! I created a new module with a javascript file in the scripts folder, but I do not know how to let that file access jQuery which is already included in Orchard or how to get the file to run its code on the page. Do I need to create a view that includes this javascript file or do I just need to create a resource manifest that includes my javascript file? Thank you for your help thus far.
Aug 29, 2014 at 8:02 PM

I received some new directions and due to the possibility of javascript being turned off in the browser I cannot use javascript to bind an onclick event to all <a> elements. Would it be possible to use a controller or some setting within Orchard to have the server hijack all links and stop them from going to their url and instead go to the speed bump page? I can still use the query string to append the url to the url of the speed bump page so the speed bump page can redirect to that url. I can also run javascript on the speed bump page as long as the page will not redirect the user to the requested url when the browser has javascript turned off.
Aug 29, 2014 at 10:51 PM
If you want to process your HTML serverside by modifying <a> elements, there's two ways that come to mind:
  1. Implement an IHtmlFilter (see my comment on your other question)
  2. Implement a custom ActionFilter (by inheriting a custom class from FilterProvider and implementing IActionFilter, and capture whatever HTML is being generated, and process this. Look at Orchard.OutputCache to see how it's doing this to implement output caching.
Aug 29, 2014 at 10:57 PM

I have gone back to my original modifications on the TinyMce module that allow a speed bump to be included as part of a url by changing the url to /speedbump?url=www.exampleurl.com This I was told will be the best way of implementing our speedbump but I need to change my speedbump page from being a "page" content type that runs some javascript to a serverside page, this way a hacker can not get into the javascript and mess with the speedbump. Any ideas on how I can create a custom page that runs the redirect code on the server instead of on the client side?

my current implementation of the speedbump uses the following javascript:

function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
    vars[key] = value;
return vars;

var transferurl = getUrlVars()["url"];

I need a way of recreating this but on the server instead.
Aug 29, 2014 at 11:20 PM
Do it in jQuery, if your boss says that it doesn't work on JavaScript then I would suggest to convince them to ignore the users who don't have JavaScript. It might represent less than 2% of the internet traffic, and probably even less on your website: http://www.searchenginepeople.com/blog/stats-no-javascript.html
And even for these people you website will work just fine, it's just you won't be able to do the speed bump.

And by the way, what would your website look like without any javascript ? Would you get usage statistics ? Or other features that will depend on JavaScript ?
Aug 29, 2014 at 11:42 PM
How would I utilize jQuery within a content type?
Aug 29, 2014 at 11:46 PM
What do you mean by that?
Aug 29, 2014 at 11:48 PM
I need to utilize an ajax call to a c# page that contains a list of valid urls the speedbump will redirect to. The c# code should look at the url that is being passed in the query string and then determine if it is a valid url in the "whitelist" of urls. If the url is valid then it should return true or something to the jquery and then the jquery will redirect to the url if false is returned then the jquery will not redirect to the url.
Aug 29, 2014 at 11:49 PM

When you create a content item such as a page you can view the "source code" and add custom javascript that will be run on the page. Is it possible to use jquery here instead of just javascript?
Aug 30, 2014 at 3:07 AM
I don't see why not. You can override the content template for your content type and register scripts from there. E.g. copy the Content.cshtml view from Orchard.Core/Contents/Views to your module's (or theme's) folder and rename it to something like: Content-MyContentType.cshtml.