Functional Flow

Introducing PreSharp

| Comments

Background

Back in 2004, I was doing some code-generation work as part of the OBIWAN project. When I started, CodeDom was being used to do the work, but I really didn’t like it because it made the generator code very hard to read and modify. Realistically, I would not need to support any other language than C#, so I started looking for alternatives. CodeSmith was very popular at the time for generating type-safe collections (.NET 2.0 generics didn’t exist yet), but it was targeted at one-shot generations, and not at creating code generation code. Then I found a very simple tool named CodeGen that appealed to me. I had been playing around with the Boost Preprocessor library recently, so I really liked the idea of using the preprocessor. I did a few tweaks to it and was able to use it for my needs at the time. Later on, around mid-2007, I needed to do code-generation again, so I took this tool and added a good amount of more power to it. At this time, it was very far apart from the original code, so I re-baptized it as PreSharp and published it to CodePlex. I never got around to do any documentation for it, so I’m making this post to try to compensate for that. I also moved the project recently from CodePlex to GitHub.

Microsoft: Please Eat Some More of Your WPF-flavored Dog Food

| Comments

I have  a love-hate relationship with WPF.

I think it is several orders of magnitude better than Windows Forms and gives developers a tremendous expressive power to materialize their ideas into good user interfaces. I wouldn’t dream of doing many of the things I was able to do in just a few weeks in the Agile Platform IDE in any other UI framework, even if I was given months. It’s like going from plain C to C# 4.

But even though the concept is really good, the quality and completeness of the concrete implementation are really not there. There are just too many quirks, weird limitations, parts that don’t play nice with others, performance problems, memory leaks, etc… And when things don’t work as they should, many times you really have to go out of your way to be able to fix things.

I understand deadlines and priorities, and I know that probably Microsoft just had to ship something at some point, but it really seems that there was a big lack of dogfooding in the WPF case.

There’s a striking example of this: what was the number one complaint that developers had about WPF since 2006?… Blurry text and images. And when did Microsoft fix it?… Only in 2010, when they started using WPF for Visual Studio.

Another issue that has been bugging me since I started using WPF was the airspace limitation. It seems that it’s finally going to be fixed in 4.5. Why do I think it’s being solved now? Because they probably needed some native WinRT component to play nice with WPF…

I think eating you own dog food is really important. At OutSystems we use our product to build all web applications: the R&D apps (bug tracking, project management, continuous integration…), the HR apps (directory, vacations, recruiting…), the sales apps, the marketing apps, the corporate site, the community forums, etc… And I can say with a great deal of confidence that if we didn’t do that, our product wouldn’t be half of what it is today.

Bottom line: we as developers should always try to eat our own dog food as much as we can. In fact, I think it’s so important that it should have been item 13 in the Joel Test.

Migrating From SubText to BlogEngine.NET

| Comments

My blog was running in SubText, but I’ve recently changed to BlogEngine.NET. The main reason for the change was that BlogEngine.NET supports storing the data in plain XML files, without having any dependency to a database. This makes it really easy to customize, as I can develop everything in my local machine, and then just send the files to the server. With SubText this was harder to do, so I ended up doing fewer tweaks, and doing them directly in production, which I didn’t like.

The migration wasn’t as smooth as I though it would be, so here are the steps I took, in case someone needs to go through a similar process:

  • Exporting to BlogML and then importing didn’t work correctly. After exporting, I had to convert the content from Base64, replace the &’s in the titles with &, and then manually set the author in all post. I also had to set the tags manually in all posts, as in SubText they weren’t a separate field but instead were part of the content of the posts. Having the posts on xml files on disk rather than on a database eased this job a lot.
  • The TinyMCE bundled in BlogEngine.NET doesn’t support images, so I had to replace it with CKEditor and CKFinder.
  • The SubText post URL's have the format /archive/year/month/day/name-of-the-post.aspx, while BlogEngine.NET post URL's have the format /server/post/year/month/day/name-of-the-post.aspx. I had to set up redirection so the old links would keep working. To do that I’ve taken the source code from BlogEngine SEO Redirection extension and changed the comparison to only check prefixes (source code here).
  • Several of the extensions available out there don’t work out of the box with the latest version of BlogEngine.NET (2.5):
    • For the AddThis extension I had to add some missing using’s to the code, and disable the form validation of the settings page (source code here).
    • To be able to configure widgets in the AllTuts theme, I had to make a small bug fix (as described in Janier Davila comment here)

After all that work, now I have a setup that allows me to tweak the blog very easily. I have it on GitHub, cloned into my local machine and into the server. I can play around locally, and when I’m glad with the results I just need to do a git push locally and then remote desktop to the server to do a git pull and force a reload of the application by touching the web.config.

Of course, to protect my passwords and keys, I have to tell git to ignore users.xml, akismetfilter.xml and recaptcha.xml, using this procedure. And I also must take care with the email settings that are stored on the global settings.xml file, which forces me to always have that file uncommitted at the server, but other than that, it’s orders of magnitude better than editing directly on production.

Agile Platform 5.1.1

| Comments

We’ve recently released version 5.1.1 of the Agile Platform. It’s got a lot of great new features and an improved look & feel. And better yet, it’s compatible with 5.1.0, so you don’t need to upgrade your server.

Check the post New-in-the-Agile-Platform-v5.1.1 for more info.

How to Change Word 2007 Citation Style to Use Square Brackets

| Comments

This one was not easy to discover, so I’m going to post it here for future reference.

In C:\Program Files\Microsoft Office\Office12\Bibliography\Style\Iso690Nmerical.xsl change the following lines:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<xsl:template name="templ_prop_OpenBracket" >
    <xsl:param name="LCID" />
    <xsl:variable name="_LCID">
      <xsl:call-template name="localLCID">
        <xsl:with-param name="LCID" select="$LCID"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="/*/b:Locals/b:Local[@LCID=$_LCID]/b:General/b:OpenBracket"/>
    <xsl:text>[</xsl:text>
  </xsl:template>


  <xsl:template name="templ_prop_CloseBracket" >
    <xsl:param name="LCID" />
    <xsl:variable name="_LCID">
      <xsl:call-template name="localLCID">
        <xsl:with-param name="LCID" select="$LCID"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="/*/b:Locals/b:Local[@LCID=$_LCID]/b:General/b:CloseBracket"/>
  </xsl:template>

to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  <xsl:template name="templ_prop_OpenBracket" >
    <xsl:param name="LCID" />
    <xsl:variable name="_LCID">
      <xsl:call-template name="localLCID">
        <xsl:with-param name="LCID" select="$LCID"/>
      </xsl:call-template>
    </xsl:variable>
    <!--<xsl:value-of select="/*/b:Locals/b:Local[@LCID=$_LCID]/b:General/b:OpenBracket"/>-->
    <xsl:text>[</xsl:text>
  </xsl:template>


  <xsl:template name="templ_prop_CloseBracket" >
    <xsl:param name="LCID" />
    <xsl:variable name="_LCID">
      <xsl:call-template name="localLCID">
        <xsl:with-param name="LCID" select="$LCID"/>
      </xsl:call-template>
    </xsl:variable>
    <!--<xsl:value-of select="/*/b:Locals/b:Local[@LCID=$_LCID]/b:General/b:CloseBracket"/>-->
    <xsl:text>]</xsl:text>
  </xsl:template>

Agile Platform Tips & Tricks #7

| Comments

How to change the page styles dynamically at runtime

[Edit 01/09/2001: Updated the sample to also override the colors in the popups]

Service Studio gives you a few good options to define style sheets for you pages and emails. Besides the global style sheet that applies to the whole eSpace, you can add a custom style sheet to each web screen and email, and you can even define a custom style sheet for each web block. The platform will take care of including all the style sheets in the html of the page/email according to the following order:

  1. The style sheet of all the web blocks directly or indirectly included in the page/email (including referenced ones), from the inner most blocks to the outermost blocks in case of nesting
  2. The eSpace style sheet
  3. The style sheet of the web screen or email.

In web screens, all those style sheets are deployed to separate files and referenced by the page, while in emails, their content is merged together and included inline in the html for optimal display in the majority of email clients. The platform also applies some post processing to the content of the style sheets to optimize their usage in content delivery networks.

All these style sheets are statically defined at design time and can’t be dynamically changed at runtime, but it’s possible to include more style sheets at runtime that override the static ones. That allows us to do cool things like giving a specific user a different style sheet, changing the color scheme to red when some critical situation is happening, or even letting the user choose the style sheet of his preference, like this:

 image

To accomplish this, we need to do two things:

  1. Make sure the extra style sheets are deployed together with the application
  2. Manipulate the html returned to the browser to include a <link rel=”stylesheet”> tag in the <head> section

For #1, we can create the .css text files outside Service Studio and then import them as resources by using the Import Resource operation available in the eSpace tree context menu. However, that’s not a very manageable solution. An alternative way is to create a set of web blocks that we don’t use in any page, and use them just to define these style sheets. The platform will still deploy their style sheet files, even if the blocks themselves aren’t used, and we can then reference those files in the page.

For #2, the AddStyleSheetTag action from the HTTPRequestHandler extension seems an obvious choice, but that will put the <link> tag at the beginning of the <head> section. As we want our dynamic style sheets to override the static style sheets, we must include them at the end, so this option doesn’t work for us. Fortunately, we can also do this easily by using a little bit of JavaScript. For a complete example, take a look at this eSpace:

DynamicStyleSheet.oml

Agile Platform Tips & Tricks #6

| Comments

Calling Screen Actions from custom JavaScript events

Imagine you’re using the Tabs_ClientSide from RichWidgets and you’re showing a list in each tab. Instead of loading all the lists when the screen is loaded, you want to only populate each list when the corresponding tab is activated. The Tabs_ClientSide already provides a way to call custom JavaScript code on tab activation, so if we could call a Screen Action from JavaScript code, we could make that Screen Action refresh the table on the corresponding tab. So, how can we do that?

The AJAX capabilities of the Agile Platform already allow you to trigger the execution of Screen Actions when some standard JavaScript events are raised. For example, if you specify a Screen Action in the OnChange property of an Input widget, when the end-user types in something in the correspondent input displayed by the browser, that Screen Action will be called at the server. To do this, the Agile Platform generates custom JavaScript code that will send an AJAX request to the server when the native onchange event of that input HTML element is triggered. So, if we add an hidden Input widget to the page and on the OnTabActivation parameter of the Tabs_ClientSide we put some JavaScript code to trigger that onchange event manually, we know that the platform will take care of calling the Screen Action specified in the OnChange of that Input widget. This way we can put there the logic to refresh the list inside the tab that was activated in that Screen Action. Unfortunately, we have no way of telling to pass the tab which was activated as a parameter of that Screen Action, and that forces us to have to an hidden Input for each tab, and decide which hidden Input to trigger in JavaScript.

Fortunately, there’s a simpler way to do this. It involves using the OnNotify property of a Web Block widget, call it by using OsNotifyWidget JavaScript function,  and in the associated Screen Action using the NotifyWidgetGetMessage built-in action to get the tab that was activated. Instead of explaining it in detail, I’ve made a sample eSpace that exemplifies this scenario. Here it is:

FruitsAndVegetables.oml

Agile Platform Tips & Tricks #5

| Comments

When you need to change a public element of an eSpace, such as an Action or a Web Block, it’s good to know before-hand where that element is being used, so you can anticipate possible problems. To do that, you can go to Service Center and check the References tab in the page relative to your eSpace. There you will find listed all the consumers of your eSpace, and if you click on the Details links next to each consumer eSpace, you can check which specific elements are being used:

image


To help to improve this process, I’ve recently published the References Dashboard component on the OutSystems Network. It has similar functionality to this tab of Service Center, but the consumers are grouped by element instead of by consumer eSpace, allowing for faster search:

image

Agile Platform Tips & Tricks #4

| Comments


If you seen this post on the Agile Network Forums - Usability Tip (Ctrl+shift+click) - you already know a quick way to get some extra space between two elements in a flow.

From 5.0.2.9 up, there’s an even easier way: just drag the the element, and if there’s little space, the flow will be automatically arranged:

Agile Platform Tips & Tricks #3

| Comments


In the previous post, I showed an accelerator to easily create a Query for an edit or show screen by dragging an Input Parameter of an Entity Identifier type to the Preparation. In 5.0.2, there’s an even easier way to do this.

Create the EditRecord or the ShowRecord and drag the Entity on top of it. Then, if there’s an Input Parameter of the correspondent Entity Identifier type, a suggestion will appear in the Source Record property: