Introducing… Dynamo – A Scriptable DotNetNuke module
Introduction
Imagine, for a second, you have a server sided JavaScript interpreter built right into a Content Management System. It should have full access to the entire Server sided API’s, depending on security requirements of course. You could literally treat source code as content. That is what this post is about.
If you have ever created a module for DotNetNuke you probably have spent (wasted) countless hours mucking around with Visual Studio, IIS, the file system, packaging, deploying, etc. It didn’t matter if they were the most complex modules, or a simple Hello World module. In the end you probably have come to the conclusion that there just has to be an easier way of doing this.
Enter Dynamo.. (Sorry for the lame name…)
Essentially Dynamo is a DotNetNuke Module which uses Jint under the covers.
Dynamo allows you to completely skip Visual Studio, the debugger, IIS, deployment, packaging, etc... Install this single module and open your DNN installation to the world of dynamic language interpretation.
Since DotNetNuke is a content management system, Dynamo brings your source code directly into the DNN UI. It allows you to create code, on the fly, and manage that code within DNN itself.
A screenshot might help clarify…
As you might not be able to interpret from the above screen shot, this is a server sided scripting language built right into DotNetNuke. In the Scripting Window you edit your script and either Preview or Save it. Notice the fancy syntax highlighting, just no intellisense. When viewing the module it will interpret and render the script at the server side. So the above example produces:
The echo method will emit text to the output container directly. Anything return’ed out of the function will also get slapped into the output container automatically. So you can either use a StringBuilder to append up your content, or just echo content directly. Watch out for Page.Response.Write, it will emit the content at the top of the page; which is consistent with ASP.NET’s rendering.
Examples
Another real world example would be to reproduce (at a very rudimentary level) the Feedback Module which ships with DotNetNuke. Here is the code block:
1: echo("<div valign='top'><fieldset><legend>Provide Feedback</legend>");
2: echo("Your Email:<br /><input type='text' name='fromemail'><br />");
3: echo("Subject:<br /><input type='text' name='subject'><br />");
4: echo("Body:<br /><textarea name='body' rows='10' cols='50'></textarea><br />");
5: echo("<input type='submit' value='Send Feedback'><br />");
6: echo("</fieldset></div>");
7: if(Page.IsPostBack) {
8: var fromemail = get("fromemail");
9: var subject = get("subject");
10: var body= get("body");
11: if(fromemail!="" && subject!="" && body!="")
12: return DotNetNuke.Services.Mail.Mail.SendMail(fromemail, "toemail@localhost", "", subject, body, "", "", "", "", "", "");
13: else
14: return ""
15: }
16: else {
17: return "";
18: }
So you should first notice that Dynamo does not support context switching between plain HTML and Code Blocks. Everything is a code block. If you want to emit HTML, you must do something like:
echo("<div valign='top'><fieldset><legend>Provide Feedback</legend>");
Mixing HTML and code is a nice-to-have in the ole product roadmap for the project.
Next you will notice the code itself is a slight mix with JavaScript syntax and .NET Types. The interpreter has the ability to mix each and interpret it accordingly. This also includes being able to call into the DotNetNuke API library as well. It’s important to note that we are using an interpreter and NOT using Reflection.Emit(). Thus we are just fine within Medium Trust.
What else can Dynamo do? Here is a short list of tested scenarios:
- Consumes RSS Feeds (uses RSS.NET)
- Full Database CRUD
- Full Access to the DNN API, including but not limited to Portals/Tabs, Modules, Users, etc..
- Emitting custom JavaScript and CSS (into the Head tag, or CSS inline)
- Detecting PostBack’s
- File I/O
- Rendering files (into the interpreter, and getting the results)
- Twitter Timeline
- Page caching
Your options you have are literally limitless.
Debugging
Since DotNetNuke is Web Based it would be extremely hard difficult to get stuff like intellisense and full step by step debugging working. I don’t have the time right now, but you never know with a future version of the product.
For now, I have the ability to “Show Debugger Details”, in the Edit Script control, when you hit Preview. It literally will emit debug information at each step of the code as it interprets it. I did a simple dump of the Current Statement and the locals available.
With that said I don’t block any exceptions and do bubble them up to the UI, so if you do have issues they will very obvious.
Source Code Versioning
Most professional software developers do use some sort of Source Control software. Right now the tool does NOT have anything built in to help with this. I would love to add this at the very least to the product backlog. Eventually I would love to get to it…
Security
The source code itself contains the line of code which completely disabled all security validations. You can do some serious damage with this. If this bothers you, you should do one of two things:
1. Find the line: JintEngine.DisableSecurity(); Remove it, recompile and redeploy to your server
2. Don’t use this package version in production.
Getting started
There are two methods for you to get started; the easiest method would be to use the prepackaged module installation file here. Download it, and install it into your Development DNN Installation site. The module’s name is “Dynamo” and should be available for you to drop on a page.
The more difficult method would be to grab the source code, and compile it. This would be the method you would need to take in order to re-enable the Security (See the Security section above). This is what I use when building/testing the module itself. So if you need to make other fundamental changes you will need to do this as well.
I would recommend you reset your references to the DotNetNuke specific DLL’s out of your actual bin folder for DotNetNuke. Once you have it building, I personally just use xcopy deployment to the website’s bin and DesktopModules folder and refresh the browser. Debugging can easily be done by setting the breakpoint and attaching VS.NET to w3wp.exe.
4 Comments
Comments have been disabled for this content.
Sébastien Ros said
Hi Rob, Thanks for your work. As I have done Jint and that I am now working on the Orchard CMS team at Microsoft, the only thing I can do is to ask you to do it on Orchard, you'll have all my support ;)
caroig said
This looks really interesting - I'm looking to giving it a try. great job.
Doris said
The download link for the prepackaged installation file is not working. It says the url querystring is wrong when you click on the I agree button.
mesut said
This is super. I'll use it to check whether the user expiration date is due or not. I don't need to write a special module for this. Even I to use for welcome message....