Journal

Tagged: module

Published on:

What I learnt today: setting up webmentions

Today was hack/build/create day at Indie Web Camp in Brighton. I already had a very basic version of a webmention endpoint running and today I wanted to implement it properly in Processwire.

After a bit of planning and defining which data I would be storing when receiving webmentions, I got down to work and wrote a basic module for Processwire. It currently only receives webmentions, but I’m planning to add the sending functionality very soon. At the moment I’m using it with brid.gy to get all the responses to my tweets into my database.

So far it works really well. When I started to work on it this morning, I wasn’t really sure if I could get it up and running in just one day. But once I was clear on how I would manage and store the incoming data, it was pretty straight forward from there. And that’s what I learnt today.

Published on:

What I learnt today: adding custom hooks to Processwire

I’ve been using Processwire for quite some time now and yet I’m frequently amazed by how easy it is to extend it’s functionality.

Today I needed to add a new method to an existing Processwire class. At first, I wasn’t really sure how to go about it but after reading the documentation, it was much easier than expected.

I wrote a module which adds a custom hook to one of Processwire’s classes. My code looked something like this:

public function init() {
  $this->addHook('Pageimage::toPicture', $this, 'renderPictureElem');
}

And that’s all there is to it really. I then wrote a function called renderPictureElem which returns some markup when called on a Pageimage class object via the toPicture() method. Because it’s that easy to deal with functionality in Processwire, I often forget that I’m really not a backend coder, or PHP programmer for that matter. But extending Processwire is pretty straight forward and adding custom hooks is no exception. And that’s what I learnt today.

Published on:

Using the <picture> element in Processwire: revisited

Some time ago I wrote a Textformatter module for Processwire which scanned the content of a textarea for <img> elements and converted them into their previously configured <picture> equivalents.

This worked well until I introduced the notes section on this website. A note may very well contain an image but unlike the images in regular articles the images in notes are not rendered per textarea field. The note template uses Processwire’s Pageimage methods to put out the URL of the image directly into the template hence the Textformatter module I had written wouldn’t apply.

Enter: ImageToPicture module

So once again I wrote a module to solve the issue. After installing it, the module adds a new method to the Pageimage class which allows rendering any image with proper <picture> element markup.

The new toPicture() method can be called like this:

$image->toPicture();

There are some options available, to define queries and image sizes. These are the defaults:

$image->toPicture(array(
  'fallback' => 450, // width for fallback image
  'altText' => '', // alternative text (default is image description)
  'sources' => array(
    '(min-width: 64em)' => 600, // queries and image widths
    '(min-width: 45em)' => 520 
  )
));

Using toPicture() without any options renders the following output:

<picture>
  <source media="(min-width: 64em)" srcset="img-600px.jpg">
  <source media="(min-width: 45em)" srcset="img-520px.jpg">
  <img src="img-450px.jpg" alt="Image description">
</picture>

A customised call might look like this:

$image->toPicture(array(
  'fallback' => 300,
  'altText' => 'My new description',
  'sources' => array(
    '(min-width: 55em)' => 860,
    '(min-width: 27em)' => 450 
  )
));

Which produces:

<picture>
  <source media="(min-width: 55em)" srcset="img-860px.jpg">
  <source media="(min-width: 27em)" srcset="img-450px.jpg">
  <img src="img-300px.jpg" alt="My new description">
</picture>

The code is available on Github – perhaps it might be useful to somebody.

Published on:

A custom posting interface for Processwire

After attending IndieWebCamp in Düsseldorf, I started posting to Twitter from my own website. I would log into the CMS I’m using (Processwire), create a new post and publish it. When published, a module would be invoked which then would automatically sent the post to Twitter.

Sounds easy, right? However the reality is that I’ve been using Twitter almost exclusively on my phone and things got a little bit more complicated. Although Processwire provides a responsive backend, creating and managing pages became too much of a hassle.

So I decided to write a simple interface myself and integrate it into Processwire. I defined the basic functionality like this:

  • Enter text and show the remaining characters
  • Upload photos directly from camera or existing albums
  • Adding location information

To integrate the interface, which would basically be a form, into Processwire, I needed two things:

  1. A page restricted to admin users where the form could be displayed
  2. A persistent session to be able to view the page without having to log in everytime I wanted to use it

First, I created a new template containing the form and the relevant fields. If sent, a PHP script creates a new page in Processwire, fills the content field and—if available—uploads and adds images and location information. It then publishes that page which invokes the already existing TwitterConnect-Module which takes it from there.

I restricted access for the template to admin users and created a hidden page. Thankfully there was already a module for persistent sessions and I didn’t have to write it on my own.

A custom posting interface for tweets

The interface itself is pretty straight forward. Images can be added using the camera or by choosing an existing one. Before adding a location, an AJAX request feeds the Twitter API with position coordinates and retrieves a list of nearby places which can then be added to the tweet.

I’m pretty pleased with the result – it works really well and I might turn it into a proper module someday.

Published on:

Scratching my own itch

I recently implemented a notes section on this website which accompanies the regular articles. There are currently three different types of notes: short text notes, photos and tweets. All of these notes are either published using the Processwire backend interface or syndicated via micropub endpoint. Each note then becomes a page in Processwire and therefore has it’s own URL.

I wanted to make adding these notes as easy as possible for me. One thing I had to consider was the fact that Processwire won’t let you create pages without a title. The title is also automatically translated into the URL for that page.

I didn’t want to enter a title each time I posted a note. I also wanted to create a consistent URL scheme that represented the date of the note’s creation. So I wrote a module that prefills the title field of a page with a configurable date string when the page is created.

The code is available on Github. It’s currently tailored to my needs, but I think it’s easily adaptable to other scenarios as well.

Published on:

Using the <picture> element in Processwire

Recently, I’ve been looking for an easy way to use the <picture> element with Processwire. By easy I mean this: the user uploads an image at a reasonable size and Processwire does the rest. (I just noticed you could interchange “easy” with “lazy”)

So I wrote a Textformatter module that allows you to do just that. Via the module configuration page you can specify multiple sizes and media queries which the module will then use as <source> elements when rendering the page. You can also provide a fallback image size for browsers that do not yet understand the <picture> element.

Module configuration page

The module uses Processwire’s image sizing capabilities and resizes the original image to the configured sizes, when the page is rendered. It then replaces all the <img> elements with the appropriate <picture> element.

You can get the module from Github. It’s still a bit hacky and I have some more features in mind that I want to add. But it does it’s job quite nicely so far.