Building a command-line utility to search for WordPress content using .NET Core and System.Text.Json
Recent weeks have been busy, and many things have demanded my attention. As a result I haven’t had too much time to build things, and I love to build things. So today, during a coffee break at work, I decided to spend 15 minutes to get something built. And it would need to be something I’d actually use.
Allow me to introduce – wpAPI_CLI, a simple and fast command-line utility to search for WordPress posts and their content.
Planning
I use Microsoft To Do to track ideas and topics I’d like to write about in the future. But after I’ve written an article and published it, I often cross it over in my To Do list and move on. So I needed a tool that quickly allows me to check against my published content if I’ve written about a specific topic.
In essence, my tool would work with a simple keyword:
wpAPI_CLI.exe <keyword>
WordPress exposes a REST API, and that REST API has a Search method. My tool would need to connect with this API, and execute a search using a keyword. The structure for the API call is:
/wp-json/wp/v2/posts?search=keyword&per_page=100
I added the &per_page=100 to get a reasonable amount of results. The default is 10.
Writing code
I just refreshed my laptop (more on that in a separate post a bit later), and had to re-install Visual Studio 2019. I created a new C# (and .NET Core) Console Project, and started hammering my code out. It’s pretty simple – but then again, so is my need.
First, as I’m calling a REST API, I need System.Net.Http, and for parsing the resulting JSON, I wanted to use the new System.Text.Json.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Web;
I’ll then define a few variables in my Main() class:
string WP_HOST = "https://jussiroine.com";
string WP_API = "/wp-json/wp/v2/posts";
string WP_METHOD = "?search";
string WP_PARAMS = "&per_page=100";
I’ll pick up the keyword directly from the command-line. As I only had 15 minutes I decided to blindly trust the user (me) in inputting something usable:
string WP_KEYWORD = args[0];
Next, I’ll call the API and construct my query:
HttpClient client = new HttpClient();
var response = client.GetStringAsync(WP_HOST + WP_API + WP_METHOD + "=" + WP_KEYWORD + WP_PARAMS).Result;
And from this result, I’ll parse through all links:
var document = JsonDocument.Parse(response);
var root = document.RootElement;
var items = new List<string>();
And now items holds all the posts, which I’ll then need to parse into something usable:
int i = 0;
foreach (var prop in root.EnumerateArray())
{
i++;
// title - remove {rendered..}
var rawTitle = JsonDocument.Parse(prop.GetProperty("title").ToString());
var postTitle = rawTitle.RootElement.GetProperty("rendered").ToString();
// strip HTML entities from title
postTitle = HttpUtility.HtmlDecode(postTitle.ToString());
postTitle = Regex.Replace(postTitle, "<.*?>", String.Empty);
postTitle = Regex.Replace(postTitle, @"^\s+$[\r\n]*", string.Empty, RegexOptions.Multiline);
// postLink
var postLink = prop.GetProperty("link").ToString();
Console.WriteLine("{0}", postLink);
}
And that’s it!
Trying it out
Time to try it out! I built this to an executable, and ran it with a few keywords to test:
Future betterments
For a future coffee break, I already came up with an interesting list of opportunities to work with:
- Move the search logic (REST API query, essentially) to be hosted in Azure Functions
- Local caching
- Performance metrics – perhaps in Azure App Insights
- Better command-line parameter handling
- Highlight relevant line of text in content when it matches the keyword being search
- Consider security a bit more
For now, I’m able to use this little tool and it’s already proving to be quite useful!