Hugoware

The product of a web developer with a little too much caffeine

Posts Tagged ‘Web

Using jLinq With JSON APIs

leave a comment »

I’ve had a few e-mails asking how to perform a query on JSON data from an external source, for example Flickr Services. This post we will go over accessing Flickr data but also performing a secondary query on the information returned.

You can download a .zip file at the end of the post with the files used in the examples.

Let’s take a look at what we’re going to create…

You can see we’ve included a search box along with a few additional check boxes with options we can use for the secondary query. These options aren’t available for the API call, but we can intercept the records and apply additional filters before we use them on the page.

To start, we need to create an extension method for downloading the data from the Flickr APIs. jLinq allows you to create extension methods and plug them directly into the framework.

//extend jLinq to search Flickr
jlinq.flickr = function(search, action) {
    search = escape(search);
    $.getJSON(
        "http"+"://api.flickr.com/services/feeds/photos_public.gne?"+
        "tagmode=any&format=json&jsoncallback=?&tags="+search, 
        function(data) {
            var query = jlinq.from(data.items);
            action(query);
        });
};

This example creates a method named flickr that resides with the rest of the jLinq library. The method accepts a keyword to search with and an anonymous function that will be used to work with the data. This is because we have to wait for the server to return a response.

This means you would use the function with a search phrase and a jLinq query to perform.

//start a new jLinq query
jlinq.flickr("cake", function(query) {

    //perform a normal query and use the data
    query.contains("title", "red")
        .sort("title");
});

At this point we need to wire up all of the UI elements on the page. I won’t go into detail on this part but you can always refer to the example for help if you get stuck.

So lets take a step back and take a look at how the filtering is done for the records. You’ll notice that we can selectively perform certain parts of the query depending on which check boxes are selected.

//sample.js - line 31     - - - - - -
//if excluding titles with digits
if (flickr.ui.filterNumbers.is(":checked")) {
    query.notMatch("title", /\d/g);
}

//if requiring a photo to have a title
if (flickr.ui.requireTitle.is(":checked")) { 
    query.notEmpty("title"); 
}

//if requiring sorting of titles
if (flickr.ui.sortTitle.is(":checked")) { 
    query.sort("title"); 
}

//snip...

You’ll notice that you don’t have to chain the entire query together. You can do sections at a time. This means you can decide when certain parts of the script run and when they are skipped.

Now, we can write queries against Flickr and also perform our own secondary queries using jLinq. In this case we are sorting data and filtering out records that wasn’t part of the query to the server.

Of course, this is a simple example but is does show some of the neat ways you can you can use jLinq to help you work with JSON data.

[Sample Files]
http://hugoware.com/examples/jlinq-flickr.zip

Advertisements

Written by hugoware

August 26, 2010 at 1:12 am

Installing CobaltMVC

with one comment

Got an interesting piece of anonymous feedback today reminding me of something rather obvious…

How exactly do you install CobaltMVC?

Oh yeah… That would be handy information… and it probably should have already been released. That said, lets get right to it.

Download CobaltMVC

The new CobaltMVC site is still in beta (like the rest of the framework) but you can still download the libraries you need to get started.

Add CobaltMVC To Your Project

Unpack the files to an easy to reach location and then add them as references to your project. You don’t need to add both, the Cobalt.dll is good enough.

‘Initialize’ CobaltMVC

Next, open up the Global.asax file and include the Cobalt.CobaltConfiguration.Initialize(); call to the Application_Start method. This makes sure that CobaltMVC is set up fully before it begins processing requests.

Update Web.config (sorta optional)

This step can be skipped but it will make coding your pages less convenient since you’ll have to add the namespaces all over the rest of your project. Add the Cobalt and the Cobalt.Web namespaces to your system.web/pages/namespaces section. This opens up the extension methods used to start Cobalt commands from your views.

You’re Done!

At this point we can test CobaltMVC to see if it is working. For example, here is a command you can run on the default MVC Index view.

And you’ll get the following results…

Not bad, huh?

It is worth mentioning that CobaltMVC might have unexpected results if you use .browser files with your project. Why?

Well, part of the Initialize() call actually creates a .browser file that is used to capture rendering for content on the page.

So, if you see this file floating around in your project, don’t delete it.

Who knows what happens when too many .browser files are fighting for the same thing but I doubt it will be a good thing.

Good luck!

Written by hugoware

August 20, 2010 at 12:09 am

3 Things To Know Before Using jLinq

leave a comment »

Since I released the beta code for the new jLinq I’ve had several of the same questions show up. Here are some answers to help you get started.

Where Is ‘Manual’, Query Commands Are ‘Auto-pilot’

I’ve had a few questions where people start trying to use the where command and find that it isn’t solving anything.

As far as I can tell, a lot of other LINQ style Javascript libraries use Where as their query command and have the developer manually provide the comparisons. Granted, I don’t know the other frameworks very well (hint, I wrote my own) but a lot of the code samples look something like this.

var results = lib.From(data)
    .Where(function(record) { return record.name.substr(0, 1) == "a"; })
    .OrderBy(function(record) { return record.name; })
    .Select();

I’m sure that these libraries are doing a lot of stuff for you in the background, but the where command in itself seems like placing too much work on the developer.

jLinq approaches this differently. Instead, you’ll find many common query methods included as part of the library. These methods also evaluate the data types to determine the best way to query the property.

Here is an example, consider you have some data that looks like this.

var data = [{
    name: "James",
    permissions: ["read", "write", "delete"]
},
/* snip... */];

Instead of checking these records manually, you can use the same command for both properties and they will handle the data differently for each.

//with string types
jlinq.from(data).contains("name", "e").select(); //matches the 4th 'e' in 'James'

//with array types
jlinq.from(data).contains("permissions", "write").select(); //matches the 2nd 'write'

This reduces the typing you do since you no longer have to perform manual comparisons.

Of course, jLinq does include a where command that uses the same syntax as the example above (anonymous function), but it is recommended to create extension methods instead of using the where command.

Operators Are Query Commands Too

Operators are an important part of jLinq. Sometimes you’d like to match on more than one condition or ignore records that do not meet a certain condition. You can use operators as individual commands in your queries.

//Examples only - Shorter syntax explained in Section 3

jlinq.from(data)
    .starts("first", "a")
    .or()
    .starts("first", "b");

jlinq.from(data)
    .not()
    .starts("first", "d")

jLinq takes operators a step further by creating operator aliases for all of the query commands in your library. This means that instead of only having the query command starts you actually have 6 – starts, orStarts, andStarts, notStarts, orNotStarts, andNotStarts. The queries above can be rewritten as.

//Examples only - Shorter syntax explained in Section 3

jlinq.from(data)
    .starts("first", "a")
    .orStarts("first", "b")
    .select()

jlinq.from(data)
    .notStarts("first", "d");

It is worth noting that and is the implied default unless you provide an or – the and versions of the query commands are for aethestetics only. 🙂

DRY — I Repeat, DRY!

If you aren’t familiar with the term DRY, it means “Don’t Repeat Yourself”. The previous samples reduced some of our typing, but jLinq can actually take it a step further.

jLinq uses field and command memorizing, meaning after you say it once it is implied until you say something different.

jlinq.from(data)
    .starts("first", "a")
    .or("b")
    .or("c");

jlinq.from(data)
    .starts("first", "a")
    .ends("b")
    .or("last", "a");

The first example memorizes the command being used is starts and the field being queried is first. After that, the remaining calls to ‘or’ will repeat the previous command and field unless something else is used.

The second example shows how you can mix up commands and field names without needing to repeat yourself. Basically, here is what the query is doing.

  1. Records with first names starting with ‘a’…
  2. then records with first names ending with ‘b’…
  3. then records with last names ending with ‘a’

You can see that jLinq makes it easy to avoid repeating the same commands and field names to reduce the typing.

This is just some of the first basics to understand about jLinq. I’ll be blogging more (and writing documentation) for the next few days. Feel free to contact me with questions.

Written by hugoware

August 11, 2010 at 9:54 pm

CobaltMVC and Custom Selectors

leave a comment »

CobaltMVC is a server side templating framework that behaves just like jQuery for your Views. CobaltMVC also works in WebForms.

CobaltMVC supports a variety of CSS selectors including pseudo and attribute matching. To keep things flexible, I’ve made it so that you can create or overwrite anything built-in. This post we discuss how to create your own for your project.

Right now, if you wanted to select all of the even rows in a table then you could use the pseudo selector…

this.Find("table > :even");

Cool, but what if we wanted to create our own? Here is an example of a selector that finds ‘numeric’ HTML elements.


//called once to add it to the project
CobaltManagement.RegisterCustomPseudoSelector(
    "numeric", //the name of the selector :numeric
    (nodes, argument) => { //the comparison to use
        decimal container = 0;
        return nodes.Where(node => decimal.TryParse(node.InnerText.Trim(), out container));
    });

//then used from our pages like...
this.Find(":numeric");

You’ll notice there are two arguments for the method you provide – First is a list of the available nodes to compare against. The second is an optional ‘argument’ string. The method should return a list of nodes that should be kept in the selection.

And the argument? That is an optional value in case you want it included in your selector. A good example of using the argument is the nth pseudo selector which returns every x number item.

//Everything within the parens is included as part of the argument
this.Find(":nth(4)");

Note: The argument is passed as a string so you’ll need to perform any parsing before you begin using the value.

Attribute selectors match against the attributes of the HTML elements. CobaltMVC checks the values and makes sure that two string are passed (even if they are empty), but any additional parsing needs to be done as part of the method.

That said, the method you use to perform the comparison is slightly different.

CobaltManagement.RegisterCustomAttributeSelector(
    "%", //the prefix to use for the selector @attr%='value'
    (argument, value) => argument.Equals(value, StringComparison.Ordinal)); //the comparison

The special character is what you want to prefix the attribute selector with (if you plan to override the default = selector then you just pass in an empty string). This needs to be a special character so not to be confused with the name of the attribute.

The comparison method itself is just a pair of strings, the first being the argument provided by the user and the second being the value found on the attribute. If the element doesn’t have the matching attribute then it is skipped entirely.

So, we could use the method we created in the example above by using…

this.Find("[@title%='Hugoware']");

Pretty neat!

If you haven’t downloaded Cobalt then head out to GitHub and download the code!

Written by hugoware

June 6, 2010 at 11:08 pm

Sienna MVC

leave a comment »

This last week has been a time of mourning for me but I have reached the acceptance phase. Now, that I’m ready to move on I can share some code I’ve been working on.

I’ve blogged a lot before about using WebForms and more recently using WebControls with ControlAdapters in MVC, but for the most part it was just messing around with small sections at a time. Tonight I published my templating framework on GitHub called Sienna.

Before you read further realize that this is not WebForms in MVC. This is WebControls in MVC — or basically the templating and using code behinds for View logic.

I might be alone on this but I am having a hard time of letting go of using code behinds for separating code from the page markup. No matter how simple a view is server side blocks of code are ugly. They are difficult to read and even harder to refactor, which is something that code behind files still excel at.

Sienna makes it so you can create new instances of Pages, assign to properties and then return them as ActionResults. To take it a step further, Sienna uses ControlAdapters to render cleaner markup and avoid the junk IDs that ASP.NET typically spews out… yes, and it drops the ViewState as well 🙂

Let’s look at an example of how Sienna works. Below is a sample page from a blog engine web application.

[/Views/Index/BlogPost.aspx]

<%@ Page Language="C#" 
    CodeBehind="BlogPost.aspx.cs" 
    Inherits="Site.Views.Home.BlogPost" %>
<html>
    <head runat="server">
        <title></title>
    </head>
    <body>
        <h1 id="name" runat="server" />
        <div id="posted" runat="server" class="date" />
        <div id="content" runat="server" />
        
        <form id="commentBox" method="post" action="[controller:Home][action:Comment]" runat="server" >
            <input id="email" runat="server" type="text" _id="email" _name="email" />
            <textarea id="comment" elementname="comment" runat="server" ></textarea>
        </form>
    </body>
</html>

[/Views/Index/BlogPost.aspx.cs]

using System;
namespace Site.Views.Home {

    //displays a blog post
    public partial class BlogPost : System.Web.UI.Page {

        //the post to publish display
        public Post Post { get; set; }

        //display the content
        protected override void OnLoad(EventArgs e) {

            this.Title = this.Post.Title;
            this.name.InnerText = this.Post.Title;
            this.content.InnerHtml = this.Post.Content;
            this.posted.InnerText = this.Post.Created.ToShortDateString();

            //add the classes for the date
            this.posted.AddClass("newest-post");

            //handle showing comments or not
            this.commentBox.Visible = Visitor.IsLoggedIn;

        }

    }

}

This might be a small amount of code but there are a lot of things to explain about it. I’ll focus in some of the more relevant parts.

  • Instead of using the built-in WebControls in ASP.NET we are using regular HTML controls that have been marked to be handled by the server.
  • Because ‘id’ and ‘name’ have special meanings to ASP.NET, we can use _id and _name to define the actual IDs to display, otherwise, no ID is shown. This allows a control to be available to the code behind using one ID and then rendered using another (or none at all). You can also use elementid, displayid or actualid if you do not like using underscores.
  • Attributes like href and src can use a special format that will be parsed by a URL helper in the background at render time. The format is [name:value][otherName:otherValue].
  • Because we use HTML elements for the template, we have access to the InnerHTML and the InnerText properties to assign values. Additionally, Sienna includes additional HTML helper methods for other common functions.
  • This example shows a normal Page as the type but you can use anything that inherits from the Page type — including ViewPages, which will give you access to the Url and Html helpers. If you aren’t using a ViewPage, the UrlHelper and Controller instances are stored in the Page.Items property.

Now, how would you actually use this view from a controller? Well, it is really quite easy…

//shows the latest blog post
public ActionResult Index() {

    //get the content
    BlogPost post = BlogPostRepository.GetLatest();

    //create the view and assign the value
    var view = this.CreatePage<Views.Home.BlogPost>();
    view.Post = post;

    //show the page
    return this.Page(view);

}

And that is it – The PageResult is returned and executed normally and the final result is nice and clean HTML output.

<html>
    <head>
        <title>My Post</title>
    </head>
    <body>
        <h1>My Post</h1>
        <div class="date newest-post" >10/15/2009</div>
        <div>
            <!-- snip... -->
        </div>
    </body>
</html>

You can also use this same approach to assign directly to properties on the page. For a second example, let’s say our code behind actually looked like the following.

using System;

namespace Site.Views.Home {

    //displays a blog post
    public partial class BlogPost : System.Web.UI.Page {

        //the name of the post to show
        public string Name {
            get { return this.name.InnerHtml; }
            set { 
                this.name.InnerHtml = value;
                this.Title = value;
            }
        }

        //the content to display
        public string Content {
            get { return this.content.InnerHtml; }
            set { this.content.InnerHtml = value; }
        }

        //the day the blog post was created
        public DateTime Posted {
            get { return DateTime.Parse(this.posted.InnerHtml); }
            set { this.posted.InnerText = value.ToShortDateString(); }
        }
    }
}

The nice thing about this approach is that the View defines which properties need to be encoded by using the InnerText or InnerHTML properties. It also allows us to assign other types like DateTime but then the View determines how to use it. Depending on how you look at it, this approach replaces the ViewModel by filling both roles at once.

Unfortunately when we create this control the links between the HTML elements and the properties are not immediately available. That doesn’t take place until after the page starts to render. So, to solve this we can assign to the Init event as part of when we create the Page.

//shows the latest blog post
public ActionResult Index() {

    //get the content
    BlogPost post = BlogPostRepository.GetLatest();

    //show the page
    return this.Page<Views.Home.BlogPost>(page => {
        page.Name = post.Title;
        page.Content = post.Content;
        page.Posted = post.Created;
    });

}

And our page is correctly created and rendered into view!

Technically, this whole approach should work with existing WebForms pages by allowing you to use MVC Controllers and Routes and then returning the correct page automatically. Of course, this hasn’t been tested and I really don’t recommend that you use it that way… but still interesting to think about 🙂

Sienna works with MVC projects so you don’t need to start anything over. Simply add the files to your project, generate the Browser definitions file (which is part of the ControlManagement class in Sienna) and off you go!

[Source Code: Sienna]

So go try it out and let me know what you think!

Written by hugoware

May 9, 2010 at 11:08 pm

Testing ASP.NET Sites for iPhone

with one comment

Writing a iPhone version of a website it can be a slight pain. After writing some code you have to upload it to a public location so you can browse to it with your phone. Even though you can browse the site you are still somewhat limited in your debugging options once your site is on a remote server.

You might have read before how impressed I am with the Mono project. You can fire up a Mac, import and existing .NET project and more than likely it is going to run just fine.

So here is the cool thing – You have a pretty good .NET IDE (MonoDevelop) on the Mac and you also have a built-in iPhone simulator. Browse to the local test server and…

Cool!

I’m not sure all the options available for debugging in MonoDevelop (or mostly for the ASP.NET side) but since you are running the test server then you have more options available to you than if it ran on another website (for example writing debugging messages)

Naturally, this will work for regular ASP.NET sites as well as MVC. In fact, anything that runs a local server for testing should be able to do this without a problem.

Anyways, certainly not the greatest thing ever but something fun to mess around with and another example of just how useful Mono can be.

Written by hugoware

February 4, 2010 at 10:58 pm

Yet Another jsshell Update

with 4 comments

I’m pretty psyched about jsshell right now. The user count is growing, I’ve had a lot of good reviews — I’ve even noticed that my blog is being hit with search for it.

I’ve also been getting feedback of ideas and suggestions which I’ve implemented and uploaded to the extension website (so you can go download the new version now).

More Intellisense

The intellisense now includes jQuery commands, jLinq commands and jsshell commands, each labeled with their own color. Additionally, there is now a slight delay before the intellisense is polled. This time limit is 100 milliseconds (so really if you aren’t typing a fast or even pause for a moment you should see it).

Automatic jQuery Help

I received this interesting suggestion from a user. Automatically open the jQuery website with the correct help information for the word that the caret is currently over. Brilliant!

Now, when you press CTRL+? or CTRL+F1, whatever word you have the caret will be opened on the jQuery website. If you don’t have the whole thing typed out, it will take a guess at what you meant. If it can’t even find a command by that name in jQuery then no window is opened.

Import and Export Settings

I’m not entirely certain what happens from version to version for Chrome extensions, I’ve added an export and import option for settings. Right now it just returns a string that you can import back into jsshell. In the future I’ll be adding an interface to do that for you. For now you might want to save any built in commands before you upgrade versions.

If you have any other feedback, please let me know!

Written by hugoware

January 27, 2010 at 11:03 pm