Awesomify anything or anyone with OpenFaaS!

While I’ve been lurking about the OpenFaaS Community I haven’t really had the wherewithal to actually get myself knuckled-down to build something that might be classed as useful or fun. To remedy that I finally came up with a new idea for a function that I can publish into the FaaS Store. I’m calling this function “Awesomify”. It will take any text you throw at it and make it awesome! Photo by Jon Tyson on Unsplash First thing I need is a Kubernetes cluster. After a quick trip down to Marks and Sparks to fill my trolly with juicy servers, I remembered that this is supposed to be serverless computing, plus M&S is a clothing store so I wouldn’t get servers there anyway. Putting the servers back on the shelves I instead fired up Google Cloud’s dashboard and ordered some Kubernetes with a side order of Chips (Fries for folk over the pond). Following the OpenFaaS documentation and my serverless system is now fully deployed, and it was easy (mostly, I had a couple of hiccups from following the docs too closely which I’ve filed bugs about so they should get resolved soon). The function Now to my function. Which language or framework should I use to build it? NodeJS? Pass. Go? Hmm, interesting idea, but nah. BASH? Now you’re talking; you can’t get more esoteric than that! Let’s write an entire function using BASH… Photo by Luca Bravo on Unsplash For my function to work, I need some sound clips. So pulling out my scissors I found a cassette of Tegan and Sara’s greatest hits and started hacking away. After 36 hours of toil, I finally had a series of clips that are usable and a large pile of wasted audio tape. The only thing missing now is a voice generator. While I could use a cloudy serverless service such as Amazon’s Polly or Google’s Cloud TTS I decided that open source was the way forward. There’s a little-known project called Mycroft which creates a completely open source Intelligent Assistant like Amazon Echo, Google Assistant, or Apple Siri. They have released a piece of code they named “Mimic” to perform text to speech duties. As an aside, my good friend Alan Pope from Canonical lent his voice to the Mimic TTS engine and the Mycroft assistant so this choice of engine was even more fun for me. With the function taking shape I felt ready to publish a trial run onto my test cluster on Google Cloud. Two hours after publishing it and tweeting a few times the function has been hit 396 times and nobody has complained since I increased the timeouts and minimum instance count from their defaults. Photo by William Stitt on Unsplash And we’re off to the races! A Pull Request is now into the OpenFaaS Store GitHub repository to add the function for anybody to use with a simple clickity-doodle. If you don’t have or want your own instance of the function you may use the test that is still operational. You just need to point your web browser to By changing the text after the “?” you can tailor what is awesome to your own needs. (Make sure you replace spaces in the text with a + symbol because addresses need to be “URL Encoded”) A few examples I’ve tried are: of course, I had to add one for my friend whose voice I used My source code is published at GitHub.

Pure CSS Loading Animation

Showcasing my skills in Web Development where I am constantly pushing the boundaries, here is my CSS Loading Animation. The experiment here uses CSS keyframes to achieve 60 frames per second animation without repainting the elements. To build the animated object (the spinner) I use a pair of incomplete CSS Triangle tricks. When you combine the CSS Triangle trick with border-radius you find you can curve one edge of the triangle. However, I probably reinvented this method, but I haven't seen any prior art.  The nice Home button on this site's menu bar shows how I use a single rounded triangle. As I saw that the single rounded triangle worked quite well. So, I started experimenting, leading me to the complete circle design you see in the spinner. The effect is created by hacking the CSS Triangle trick to display two opposing triangles instead of one directional arrow. This is created with two non-transparent borders instead of one, which would create a single arrow: .selector { border-left: 25px solid transparent; border-right: 25px solid transparent; border-top: 25px solid #eee; border-bottom: 25px solid #eee; } Once we have the opposing triangles we apply a 50% border radius on the element. This forces a circular appearance with two slices and two gaps. Finally, we create a sibling using the :after CSS selector providing the remaining two slices in the gaps from the first element: .selector:after { border-left: 25px solid #ccc; border-right: 25px solid #ccc; border-top: 25px solid transparent; border-bottom: 25px solid transparent; } The first example shows an effect similar to Apple's "Beach Ball". Both elements animate together. Because the same look can be achieved without two separate elements, the second demo shows a use for keeping them separate: So, we use two separate elements to create this slightly different effect. Here, we animate each pair of opposite triangles separately. The effect is somewhat pleasing:

How to make the A-Z Listing plugin for WordPress use a different Index Letter for a post

This post talks about our A-Z Listing Plugin, which is available on How did we get here? After a long battle with a very considerate person in the forums where I repeatedly failed to get them working with various attempts at writing code they could drop into their site, I decided I needed to write it up and explain how to do this once and for all. The scenario You have a series of posts with Proper Nouns (people's names) as their titleYou want to index them on their Family Name (sometimes called the "Last Name") The concept is fairly simple, in that you need to hook into the filter that I've provided and return the right result with the index letter changed. This is the rub in my attempt at helping the person on in that I really didn't understand my own code well enough, despite having written it, so I kept suggesting non-working solutions. The final code add_filter( 'a_z_listing_item_indices', 'my_a_z_index_filter', 10, 3 ); function my_a_z_index_filter( $indices, $item, $item_type ) { // make sure we're filtering the right post type if ( 'post-type-we-want' === get_post_type( $item ) ) { // pull the title and get the first letter of the second word $full_name = explode( ' ', $item->post_title ); // the last word is in the last element of $title_parts so check it is there $last_name = array_pop( $full_name ); // ensure we actually found a last name if ( $last_name ) { // cut the first letter out for our index $index = substr( $last_name, 0, 1 ); // set up a new empty array $indices = array(); // only the first names are left in $full_name. Join them together again $first_names = join( ' ', $full_name ); // Now put the last name first and separate with a comma+space from the first names $formatted_name = "{$last_name}, {$first_names}"; // add the new name associated with the item into the new array we created $indices[ $index ][] = array( 'title' => $formatted_name, 'item' => $item, ); // return a new array with our new index letter instead of the // indices already discovered by the plugin return $indices; } } // if we get here we didn't override the indices so return // those already discovered. return $indices; } The new way (Jan 2019) Since this post was published I have added a new filter that is much more friendly to use. The new filter does not require a specific format for the return value. Instead, it just needs an array of letters for the post to be indexed against. add_filter( 'a_z_listing_item_index_letter', 'my_a_z_index_filter', 10, 3 ); function my_a_z_index_filter( $index_letters, $item, $item_type ) { // make sure we're filtering the right post type if ( 'post-type-we-want' === get_post_type( $item ) ) { // pull the title and get the first letter of the second word $full_name = explode( ' ', $item->post_title ); // the last word is in the last element of $title_parts so check it is there $last_name = array_pop( $full_name ); // ensure we actually found a last name if ( $last_name ) { // cut the first letter out for our index $index = substr( $last_name, 0, 1 ); // set up a new empty array overwriting the old indices $index_letters = array( $index ); } } // return the indices item's indices return $index_letters; }

Advanced composition of Polymer Webcomponents

In a request for help sent to the Polymer web components mailing list, a user wondered about lists specifically based on the example provided in the Shop Demo that the Polymer team created. This user wanted to understand how to change the list so that it may use a different markup to the one provided for in the original example. As I thought about and researched this problem I encountered a stack overflow post that talks about a parent providing the markup for a dom-repeat template inside a child's shadow root. This lead me to experimentation with multiple levels of nesting where only the top-level element or document provided the markup templates for a list and the list items within that list. Markup included in the document My top-level document that I settled upon dictates how the children behave. Notably, each element's innards are wrapped inside a <template> to prevent display when the child elements stamp the light dom into their shadow root. <my-list items="[[items]]"> <template item-outer> <my-list-item item="[[item]]"> <template item-inner> <img src="[[item.icon]]" /> </template> </my-list-item> </template> </my-list> The reference to a variable named items maps to the following array of objects (purely an example): [ { title: "cat", icon: "" }, { title: "random", icon: "" } ] The magic isn't so much in the above invocation, but the individual elements my-list, and my-list-item. They both follow similar layout but need slight differences due to the my-list-item not being able to hijack a dom-repeat template like the my-list is able to. The my-list Element <dom-module id="my-list"> <template> <content></content> <template is="dom-repeat" id="repeater" items="[[items]]></template> </template> <script> Polymer({ is: "my-list", properties: { items: { type: Array, value: function() { return []; }, notify: true } }, ready: function() { this.$.repeater.templatize(this.querySelector('[item-outer]')); Polymer.Bind.prepareModel(this.$.repeater); Polymer.Base.prepareModelNotifyPath(this.$.repeater); } }); </script> </dom-module> The magic is achieved via the combination of the insertion point (<content></content>) providing the templated contents from the light dom, and the templatize() function. The function takes a querySelector match of the <template> tag from the light dom by matching on an attribute I assigned. Because I then assign that template to the dom-repeater template stub inside the element definition when the dom-repeat cycles through the items array and stamps itself to this element's shadow root it will use the code from the light dom as the actual rendered output for each item. This element has a property that holds the items array, which is then assigned to the dom-repeat template for iteration. The my-list-item Element With very similar behaviour to the my-list element, the my-list-item element is largely identical with only minor differences to account for using a <template> that doesn't, unlike the dom-repeat above, stamp itself to the DOM automatically. <dom-module id="my-list-item"> <template> <p>[[item.title]]</p> <content></content> <template is="dom-template" id="tmpl"></template> </template> <script> Polymer({ is: "my-list-item", properties: { item: { type: Object, value: function() { return {}; }, notify: true } }, ready: function() { this.$.tmpl.templatize(this.querySelector('[item-inner]')); Polymer.Bind.prepareModel(this.$.tmpl); Polymer.Base.prepareModelNotifyPath(this.$.tmpl); var stamped = this.$.tmpl.stamp({item: this.item}); this.appendChild(stamped.root); } }); </script> </dom-module> This element has a property which holds a single item object as provided by the dom-repeat in our parent element my-list. We follow the same pattern as in the list element excepting that, due to using a <template> which does not automatically stamp itself into the DOM, we include two extra lines of javascript, which I've highlighted in bold above. The first extra line stamps the template into a variable with the item property passed through to the template under the same name. Finally, we add the stamped template into the shadow root with appendChild(). I have immortalised the full code in a working example at Codepen What now? With this example, it should be possible to see how advanced composition can be achieved allowing for complex scenarios where supporting elements can provide for themselves to be extended without their knowledge. The example of a list taking a list-item template is the most obvious one given our nascent experience with web components, but it is clear that developing this concept can open many new patterns and behaviours. If you're a web developer and still haven't dipped your toe into the pool of web components and Polymer then I urge you to read more and try out some simple examples. Take your own website and find one thing, no matter how small, which is repeated over multiple pages but currently takes more code to reproduce than you'd like. With that thing, try turning it into a fully self-contained web component and replace ever instance of it throughout your site with an instance of the component instead. Finally start thinking of other more complex things that are repeated and try componentizing those, too. Before you know it I hope that you'll be knee-deep into the world of components and are better-off for it. Furthering your skillset Some resources that are helpful for beginner and advanced developer alike include: Real-time Polymer-specific support in the Polymer slackTransactional Polymer-specific support through the Polymer mailing listEverything web components can be found at Webcomponents.orgMany more reusable elements at customelements.ioGeneral web components real-time support in the dedicated chat

Stop discouraging women!

This post is inspired by an advert that I saw on youtube that highlights the damage that can happen to a young woman's psyche with simple behaviour patterns such as telling the woman that she needs to be pretty or even just telling her she is pretty. I thoroughly agree with the sentiment that many of our brightest female engineers, mathematicians and developers are being discouraged before they even know that they have an interest or aptitude for technical subjects. The Raspberry Pi Foundation is helping in the general push to get more children and young adults to discover the computing realm, but we still have a long way to go until the numbers of children progressing into technical subjects at college and beyond are back where they were in the late 1980s and 1990s. Moreso the disparity between male and female students on these STEM courses is very evident. We, as a society, need to encourage young adult women to discover an interest in technical or scientific endeavours. The more we can balance the scales the better and more-equal the world will be. This is not just a benefit to the communities that are currently biased toward males but the world, in general, will benefit with new points-of-view pushing technical and scientific discoveries which will filter into every-day life whether the general population realise it or not. Equality is not just about ensuring that people aren't discriminated based on gender, age, religion, race, sexual orientation, or planet-of-birth; a truly equal society benefits not just those that might previously be discriminated but those that would be the discriminators, equally!

TimThumb EOL (finally!)

The Make WordPress blog has finally signalled the end of a disastrous piece of software that made many WordPress sites insecure. TimThumb is/was supposed to allow embedding of images at any dimensions without requiring WordPress to previously have created the variant. The project has been used by many, many, themes available on commercial sites such [...]


We all receive them, and we all ignore them, but sometimes they can reveal interesting things. e.g. Don't you love spams that come from a n00bie spammer who just paid for access to a "one-click spam everyone" tool, but didn't read the documentation? What follows below is a true spam that I received today with [...]