On the project I have been working on since January this year (it’s due to go live May 1) one of the requirements was a WordPress Blog that integrated in to the site. It also called for a global search that searched both the site content and the blog and then returned all the results on a single search screen.

Now the search in WordPress is just fine so I didn’t want to re-invent the wheel and search it in another way, I just wanted to use the built in search. Fortunately this is pretty easy to do with the .NET WebClient, a url and some string parsing of the results.

The format of the standard WordPress search url is like so:

http://www.bondigeek.com/blog/?s=jQuery

Pop that url in the browser and it will perform a search for jQuery across the blog you are reading.

So now to parse the results.

The first thing I needed to do was create a standard Type that search results would be returned in. In my application I pretty much use WCF Data Services exclusively so the quick (and dirty) route I took was to create a table of the format my search results would take and then add that to my EntityFramework Model.

Personally I don’t have a problem with this approach and since I have never had any success getting EntityFramework and POCO working together and exposed via my WCF Data Services I chose this method of adding a table that would never contain any data, it was just a template.

I end up with a class structure like so in the end:

publicclass SearchResult { publicstring FriendlyUrl { get; set; } publicstring DisplayString { get; set; } }

FriendlyUrl holds the link to the content, whatever it may be and DisplayString contains the text displayed in the search results as shown below:

Search Results

(sorry, nothing interesting to show in the search results as all the test data has been cleared out Smile)

You can see from above there are 8 searches, 1 of which is the blog, and each of these is executed as an Ajax request to a WCF Data Service end-point.

The code to execute the Blog search is shown below:

[WebGet] public List BlogSearch(string criteria) { List results = new List(); WebClient webClient = new WebClient(); criteria = MiscHelpers.ODataUnescape(criteria).Replace(" ", "+"); string url = string.Format("{0}?s={1}", SiteSettings.Instance.Items.GetStringSetting(StringSettings.UrlBlog), criteria); byte[] resultBytes = webClient.DownloadData(url); UTF8Encoding decoder = new UTF8Encoding(); string html = decoder.GetString(resultBytes); while (html.IndexOf("blog-summary") != -1) { SearchResult newSearchResult = new SearchResult(); html = html.Substring(html.IndexOf("blog-summary")); html = html.Substring(html.IndexOf(""\"")); html = html.Substring(html.IndexOf("\"")); html = html.Substring(html.IndexOf(">") + 1); newSearchResult.DisplayString = html.Substring(0,html.IndexOf("<")); html = html.Substring(html.IndexOf("<") + 1); results.Add(newSearchResult); } return results; }

The process is as follows:

  1. Create a List List to return our results, or none if there are none
  2. Create a WebClient class to execute the search
  3. Do a bit of parsing on our search criteria. The ODataUnescape method is used to work around the problem of having single quotes in your parameters for methods.
  4. We then use the WebClient to execute the search passing in the criteria
  5. Using a UTF8 encoder we then decode the byte[] of results.
  6. From then on it’s just plain old parsing to pull out what we need since the results are returned as a collection of Divs essentially

Now if you use this technique you will want to look at the format the results are returned in to make sure that the parsing above works for you…which it probably won’t.

I am sure I could clean up the parsing routine above or even use a regular expression but hey it works and this has been a long project Smile

For completeness here is the javascript code to call the WCF Data Service and display the results:

function DoBlogSearch(criteria) { var url = "/data/MyService.svc/BlogSearch?criteria='" + ODataEscape(criteria) + "'"; $.ajax({ type: "GET", url: url, async: true, contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { results = msg.d; $("#BlogResults").children().remove(); if (results.length > 0) { $("#search-result-template").tmpl(results).appendTo("#BlogResults"); } else { $("#BlogResults").append("

  • No Results
  • "); } }, error: function (xhr) { returnfalse; } }); }

    And finally I am a huge fan of jQuery templates so that is what is being used to render the mark-up for the portion of the page that shows the Blog search results. HTML and Template shown below: <ulid="BlogResults"class="search-list"><divclass="loading-animation"style="top:15px;">div>ul> Hope that helps anyone wanting to do something similar.

    Cheers,

    BondiGeek