After a nice, relaxing three weeks vacation (do I need to mention that I'll be on vacation in Greece next weekJ), I thought we might have a look at a way to tweak Dynamicweb and see if we could exceed what's normally possible with it.
How often haven't you thought that it would be really cool, if you could pass an argument in a template tag and have your code on the server react to that argument? It has happened to me a number of times, and during a project I'm working on at the moment, I got sick of not being able to do this, so I decided to do something about it.
I wanted to be able to display the status of an Extranet user, so other users can tell if the user is online. First of all this requires me to subscribe to the notification that is being sent, when a user logs in and register his status. The notification is Dynamicweb.Notifications.Standard.User.OnAfterLogin.
In the subscriber code I simply want to add the ID of the user to a hashtable and store that hashtable in the Application collection of the HttpContext making it public for all users entering the site. This is pretty straight forward, just look at the code supplied in the bottom of this article - the CurrentOnlineUsers class does all the hard work.
The fun part is the parsing of the argument tags. I use a PageTemplateExtender for this since it's invoked automatically at each request, and it allows me to manipulate with the current page template.
But first let's look at the templates in use. I use the NormalEmployeePresentation.html template from the Employee module. I want to display a list of employees and their individual status. The argument will be the AccessUserId of the employee, so for the user with ID = 287 our tag will look something like:
This is OK for displaying the online status of user 287, but since we want a list of users, let's make it context dependent.
-->
The Employee module renders the tag with the proper value for each employee and leaves us with the ID (287) of the user. When the Employee module is done merging its values with this template, the resulting list of tags could be something like this:
Now let's have a look at the PageTemplateExtender. This allows us to interact with what's in our PageView object, which includes our TemplatePage object; a representation of the old template object. When invoking it's Output method, we get the HTML output from all paragraphs on the current page, including the Employee module we dealt with earlier. When running a regular expression against this output, we are able to get a collection of the tags that match the pattern for our dynamic tag:
()+
For ease of use I store each unique number in a hashtable.
CurrentOnlineUsers Users = new CurrentOnlineUsers();
Regex reg = new Regex(@"()+");
Hashtable UserIds = new Hashtable();
Match match = reg.Match(PageView.TemplatePage.Output);
For each unique number I run the SetTemplateValue method of the Template object in the PageView object and set a value indicating the online status, in this case "1" for online and "" for offline.
Note that I'm using the Template object and not the newer TemplateV2 object. This is because I cannot manipulate with the the HTML as long as it's being processed by TemplateV2. The Template class, on the other hand, allows this. The only challenge heres is the order in which the template tags are merged.
To top it of, I set a template tag containing the total number of current online users.
Template.SetTag("CurrentUsersCount", Users.CurrentUsers.Count.ToString());
Now all the server logic is in place, let's turn back to the template. Her we add a small piece of JavaScript that prints the status of the current user in the list. Online users will have 1 merged in the template, so we measure by that.
When parsed by Dynamicweb the HTML will look like this for online users:
And for offline user it will be.
I could also have merged "Online"/"Offline" into the tag, but I don’t like having my code output hardcoded text values, so I went for the other solution. It's just a matter of preference.
Using the techniques described here goes beyond outputting boolean values for template tags.Intead of matching a hard coded tag (UserOnlineStatus), you could match this instead:
+
This would allow you to retrieve the values on both sides on the colon giving you the opportunity of executing a method with an argument. Given the following tag.
And this server code
The following HTML would be merged into the page template
Calvin & Hobbes
I've wrapped a nice little package with the C# code and the template for this example for you to download. Hope you can make any use of it.
Comments
This article has no comments You need to be logged in to use this feature