Fun stuff : node.js in an Umbraco site

Did you ever want to run node.js within your umbraco site, and edit the server side javascript from within your Umbraco backend? Not? Well, it’s still a fun thing to do, don’t you think?

Update 1: I actually think nodejs makes some sense within Umbraco. Why? Well, for example it makes it possible for js-peeps to stay js. And node has a _lot_ of nice plugins (as for example jade and express).

Update 2: I made a first version of a sample of Umbraco running with ExpressJs and Jade, it uses Tapas that serves published content for requested url.

The setup only takes a few minutes to do:

  1. Install NodeJs and IISNode on your computer / server
  2. Install an Umbraco site or use an existing, using WebMatrix
  3. Add the NPM plugin from WebMatrix Gallery
  4. Add the folders iisnode and node_modules for the NPM plugin to show up in the toolbar (and restart WebMatrix)
  5. Add the Express Node module with the help of NPM. It puts the module in a new folder in your root “node_modules”
  6. Add the following lines to your web.config, in the configuration section (at the bottom for example):
...
    <location path="scripts/node">
        <system.webServer>
            <handlers>
                <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
            </handlers>

            <rewrite>
                <rules>
                    <rule name="express">
                        <match url="/*" />
                        <action type="Rewrite" url="/scripts/node/server.js" />
                    </rule>
                </rules>
            </rewrite>

        </system.webServer>

    </location>
</configuration
  • Add a new .js file and save it as /scripts/node/server.js
  • var express = require('express');
    
    var app = express.createServer();
    
    app.get('/scripts/node/hello/:name', function (req, res) {
        
    	
    	res.send('Hello ' + req.params.name + ' from node! [express sample]');
    	
    	
    });
    
    app.listen(process.env.PORT);
    

    That’s it! Now you should be able to surf to /scripts/node/hello/world and you should get “Hello world from node!” back.

    Update 2: What about Umbraco content?

    What if we like to do something a little bit more useful – make it possible to get and edit content? Well, our node application does not have the Umbraco contents available, so we need to get it in some other way : I guess http is the standard.

    Currently (in Umbraco 6.0) there is no available Restful Api out of the box (it will be added in 6.1 afaiu). However, the uRest package by Matt Brailsford seems to play nicely with u6 (edit : perhaps not, I could not get it to accept posts). Add that, and then change server.js and add a urest.js file as in this gist to get contents with internal http requests.

    app.get('/scripts/node/urest/documents/:id',function(req,res){
        var documentId = req.params.id;
        requestGetWithToken("/documents/" + documentId, function (response) {
            // just return the content to the response string:
            res.send(response);
        });
    });

    Now you can browse to the url /scripts/node/documents/{nnnn} to get a particular document.

    Check out the uRest documentation for information about how to create and edit content.

    Update 3: content straight from umbraco context with the help of EdgeJs

    I just managed to get actual content directly from umbraco context into nodejs with the help of the brilliant EdgeJs https://github.com/tjanczuk/edge by Tomasz Janczuk and https://github.com/sitereactor/umbraco-console-example by Morten Christensen.

    I will blog more details about it, but what I needed to do was this:
    1. Add Edge with the help of NPM.
    2. Create a class libary dll that fires up the Umbraco context (copied from Umbraco console example), with functions returning async Task

    public async Task<object> ListNodes(object input)
    {
      return "nodes: " + listNodes();
    }
    

    3. Setup functions inside my node app calling the .net functions

    var express = require('express');
    var edge = require('edge');
    var app = express.createServer();
    var listNodes = edge.func({
        assemblyFile: 'C:/harcodedpath-to-my-website/bin/umbracocontext.dll',
        typeName: 'UmbracoContext.Startup',
        methodName: 'ListNodes'
    }); 
     
    app.get('/scripts/node/hello', function (req, res) {         
        listNodes("",function(error,data){
            res.send(data);        
        })
    });
    app.listen(process.env.PORT);

    4. Add a node.exe.config into my node.exe folder with just a connectionstring to begin with:

    <?xml version="1.0" ?>
    <configuration>
        <connectionStrings>
            <remove name="umbracoDbDSN" />
            <add name="umbracoDbDSN"
                 connectionString="Datasource=C:\harcodedpath-to-my-website\App_Data\Umbraco.sdf"
                 providerName="System.Data.SqlServerCe.4.0" />
        </connectionStrings>
    </configuration>
    

    It’s obviously not ideal to set the connectionstring in the global node.exe folder. I think a good workaround to get local connectionstrings is to copy the node.exe to a folder within the site and set the iisnode handler to use the local node.exe instead.

    <iisnode
          nodeProcessCommandLine="&quot;c:\harcodedpath-to-my-website\nodejs\node.exe&quot;" 
    

    Edge does not make it possible (yet) to use the already existing instance of the asp.net application (share memory), so if we run umbraco in asp.net and node in parallell we will have two context instances.

    If you are concerned about the performance: read this.

    GetTreeById

    app.get('/scripts/node/getTreeById/:nodeId', function (req, res) {  
        getTreeById(Number(req.params.nodeId),function(error,data){
            res.send(data);        
        })
    });
    public async Task<object> GetTreeById(int nodeId)
    {
        var node = contentService.GetById(nodeId);
        return nodeToDictionary(node, true);
    
    }
    private Dictionary<string, object> nodeToDictionary(IContent content, bool includeChildren)
    {
        var nodeData = new Dictionary<string, object>();
        nodeData["Name"] = content.Name;
        nodeData["Id"] = content.Id;
                
        content.Properties.ForEach(p => { nodeData[p.Alias] = p.Value.ToString(); });
        if (includeChildren)
            nodeData["Children"] = content.Children().Select(child => nodeToDictionary(child, true)).ToList();
        return nodeData;
    }
    

    tree

    Advertisements

    4 thoughts on “Fun stuff : node.js in an Umbraco site

    1. hi,
      I have installed Node.js and IISNode on my machine and added the server.js in the CMS under the Scripts/node/server.js file. I have create the simple MVC web project and in the web.config file I have made the tag entry in the web.config file and tried to run the application on my machine but I am getting the error. Please note, I have tested the node.js is running on my machine by running the default “Node” website in the IIS. I have installed npm express packages also in my MVC web project.

      for ex. http://localhost:52137/scripts/node/hello/santosh

      Error :- Handler “iisnode” has a bad module “iisnode” in its module list

      Is it compulsory to install the WebMatrix on my machine? Could you please help me with this issue?

    2. hi,
      I have installed Node.js and IISNode on my machine and added the server.js in the CMS under the Scripts/node/server.js file.

      I have create the simple MVC web project and in the web.config file I have made the location tag entry in the web.config file and tried to run the application on my machine but I am getting the error.

      Please note, I have tested the node.js is running on my machine by running the default “Node” website in the IIS. I have installed npm express packages also in my MVC web project.

      for ex. http://localhost:52137/scripts/node/hello/santosh

      Error :- Handler “iisnode” has a bad module “iisnode” in its module list

      Is it compulsory to install the WebMatrix on my machine? Could you please help me with this issue?

    3. Hi Jonas,

      Thank you for your reply.

      I am experimenting with Node.js and Umbraco CMS integration but I am unable to test it successfully on local environment.

      First I have installed Node.js later I installed the IISNode on my machine.

      The default website of iisnode is working fine on my machine.

      When I added server.js and express.js in the Umbraco CMS and tried to test the Node.js and Umbraco integration but it didn’t work. Please check the following steps I did it for interacting Node.js and Umbraco CMS.

      1) Node.js installed on my machine
      2) Created the simple MVC application and downloaded the Umbraco CMS from Nuget package manager.
      3) IISNode installed on my machine and the default website “Node” works fine in IIS7.
      4)Run the MVC application and login in the Umbraco CMS and added the server.js and express.js files under Scripts/node folder.
      5) Added the location tag entry in the web.config file.
      6) Run the website once again and tried to with the below URL but I am getting the error.

      URL:- http://localhost:51494/scripts/node/hello/santosh

      Please note, I have implemented the same example which you given in your article and even kept the same name for JS files but still it’s not working it is giving below error.

      Error:- Handler “iisnode” has a bad module “iisnode” in its module list

      Could you please provide me correct steps or any other link of your article where the Node.js and Umbraco CMS integration did it successfully? Please share your email address so that I will send you screenshot as well.

      I want to just test Node.js and Umbraco CMS integration and printe some “Hello World” msg etc.

      Web.config file location tag entry:-

    Leave a Reply

    Please log in using one of these methods to post your comment:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s