Karen Attfield

Happiness Engineer at Automattic

  • Home
  • About
  • Contact

Sustainability in web design

August 11, 2017 by Karen Attfield Leave a Comment

EarthWhen you hear the word ‘sustainability’, you don’t tend to think of websites and web applications. However, the internet has an annual carbon footprint of 830m tonnes (which is 2% of all emissions, projected to double to 4% by 2020), which would place it at number 6 in the world if it were a country. Web developers are partially responsible for at least forty percent of these emissions. Some of these statistics are more than 4 years old, so these figures are likely to be even higher now. An infographic created by CustomMade provides a graphical representation of C02 emissions through internet usage.

So what can be done?

 

On a design level:

  • Good user experience – the easier it is for someone to find what they need on your site, the less pages are loaded, meaning less server requests. For example, is the navigation on your site clear and easy to use?
  • Showing resources only when needed. For example, utilising the HTML5 srcset element on pictures means you will only load the image with the correct size for the screen size you are browsing from.

On a development level:

  • An efficient, quick loading site. The quicker it loads, the more efficient it is with less processing going on behind the scenes. For example, minifying your resources (eg. CSS and JS) reduces the size of your code, reducing bandwidth usage. Similarly, using image sprites reduces the number of server requests, saving bandwidth. Where possible, consider using SVG’s.
    • Keep up with Web Performance Optimisation standards.
    • Write valid code so the browser can run more efficiently. W3C offer a free markup validation service.
  • Use a Content Delivery Network (CDN) so websites can share script files. Examples include Google’s hosted libraries (serving jQuery, AngularJS and more).

On  hosting level:

  • Choosing a host that powers its servers with renewable energy, and whose servers are efficient, is the biggest step in serving a sustainable website. Here is a short list of a few of these hosts: Netcetera (* see bottom of page) (Isle of Man), Ecohosting (UK), Any host based in Iceland
  • Use a CDN on top of your hosting service to optimise web page delivery.

 

Even after religiously applying all of these to your website, your site will still have a carbon footprint. You could choose to buy an offset –  though this won’t remove the CO2 produced – or invest in a project committed to environmental or sustainability education.

Digital Footprints

In a contradictory world, the shift of many businesses to the online world, as well as the numerous start-ups geared at saving CO2 through such ideas as car sharing and web conferences, is more than making up for the footprint that the internet itself creates.

That shouldn’t stop us from reducing our web footprints whenever possible. If we can reduce our own footprints and those of the websites we build, we should. Every small change makes a difference.

If you want to learn more, I recommend participating in Sustainable UX, a new online conference which is into it’s third year in 2018. Join in for free and listen to heaps of presentations by specialists in their fields. Topics cover digital design and climate change, asking questions such as ‘can the internet be powered by renewable energy?’, ‘how can we make the web more accessible and sustainable for all?’ and ‘what is the role of UX in combatting climate change?’.

 

For more reading on this topic, check out these sites:

Sustainable Web Design

W3C Sustainable Web Design Community Group

EcoGrader – how green is your website?

The Green Web Foundation

Mightybytes

Infographic: The Carbon Footprint of the Internet

 

(*) Note – this is an affiliate link. I will get a small % of your first purchase made if you use this link.

Filed Under: Sustainability

Adding datepicker to a WordPress form

June 12, 2017 by Karen Attfield Leave a Comment

Customizing custom-made or plugin forms with datepicker

jQuery UI Datepicker
jQuery UI Datepicker

So you’ve developed a basic contact form on a client’s site (or installed a lite contact form plugin, such as WPForms Lite or Contact Form 7), and they love it. Several months later, they get in touch with you because the business is expanding and they need a booking form added, and want a datepicker included so that site visitors can easily select dates whilst filling in the form.

No worries!

You have several options available to you – if you used a plugin you could either upgrade to a premium plan of the plugin you are using (for example WPForms basic) or add the extra functionality yourself. While you and your client may decide it’s better to pay a yearly price for a premium option, this is only hassle free if you went with a plugin that allows for upgrades, such as WPForms. Yes you could install a new contact form plugin, but do you really want two contact form plugins on your site?

More than likely you’ve added CSS styling to your forms, and you would have to start again with the new form. Some plugins such as Contact Form 7, require you to add another plugin to get the datepicker functionality as well (and at the time of writing the support for that plugin doesn’t look so hot) – and again, do you want all these extra plugins on your site, potentially causing issues if the developer doesn’t keep them updated? So, you decide to add the functionality yourself.

Editing the input field

So what we want to be able to do is to show the datepicker when we click on the ‘booking date’ input field. We then want to be able to select a date and for that date to be displayed in the field.

The first step then is to add an id for the form field you would like a datepicker added to. If you’ve custom built your form, just add the id to the input field you want to use. Let’s name the id #booking-date for the sake of this article. In it’s most basic form, your input field should look something like this:

<input id="booking-date" name="booking-date" type="text" />

This may be trickier if you used a plugin. For example, WPForms will allow you to create a class for your booking date field, but this class name is applied to the field container rather than the specific input field. Add the class booking-date to the field container – you will be able to access the input field directly using the jQuery extenstion: '.booking-date > :input' (we’ll use this in the jQuery function later).

In Contact Form 7, you can add an id to the field you want by adding id:booking-date within the square brackets for your date field.

Note: you can use Contact Form 7’s default date functionality – this implements the date attribute in HTML5. This article assumes you want to use jQuery’s datepicker for various reasons including styling and date formats, as well as browser compatibility. You can find out more about HTML5’s date attribute here ).

Enqueue the styles and scripts

The next thing to do is enqueue the datepicker script in your functions.php file, and also enqueue the datepicker theme styling. In functions.php, add the following to your existing wp_enqueue_scripts function (we don’t need to enqueue jQuery as WordPress includes and loads it’s own version of the jQuery library automatically):

wp_enqueue_script('jquery-ui-datepicker');
wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');

Trigger the datepicker function

The final thing to do is create a function in your functions.php file that will run the jQuery code that will trigger the datepicker. You can also do this in a separate Javascript file and enqueue the script if you wish. As we want the script to load in the footer, we’ll hook the php function onto the wp_footer action hook.

So at the bottom of our functions.php file we’ll add the following:

function add_datepicker(){ 
    ?>
    
    jQuery(document).ready(function(){

        $bookingdate = '.booking-date > :input';   // use this if adding a class name to the input field container or $bookingdate = '#booking-date';  
} 

add_action('wp_footer','add_datepicker',10);

How does this work?

What exactly is this function doing? The PHP function includes a Javascript function which starts by creating a variable that represents either the id name of the input field (for example if you are using a custom built form or a plugin like Contact Form 7), or the class name of the input field container if you are using the WPForms Lite plugin.

Before clicking the input, we hide the datepicker.

On clicking that input, we set up the datepicker, and then show it.

And that’s all there is to it. You can customise and style the datepicker to your heart’s content (check out the jQuery datepicker API documentation to explore the API in depth). Some time back I created a demo booking form on a static HTML page using datepicker – you can check out the code on Github for some customisation ideas.

Disclaimer: The link to WPForms on this page is an affiliate link, should you decide you’d prefer to purchase any of their premium plugin versions.

Filed Under: Web development

Custom post types & advanced custom fields in Genesis (part 2)

April 15, 2017 by Karen Attfield Leave a Comment

Setting up the custom fields

Continuing on from the first part of this two part article where we set up a custom events post type, below we’ll look at adding custom fields with the Advanced Custom Fields plugin.

The first step is to install and activate Advanced Custom Fields. Then, add a new group (give it a name of your choice, for example Event Details).

Advanced Custom Fields group set up screenshot

We’ll create one field for now, in which a date can be selected. That date represents the date that the event is considered a past event, and once that date is reached, we then want the event to show up on a different page. To set this new field, give it a label such as Event End Date. The field name will be automatically generated. Set the field type to Date Picker and add some instructions, such as ‘Mark the date at which the event will be considered a past event’. Mark whether or not you want this as a required field, and make sure you’re happy with the default date format.

In the location box, set the rule to show this field group if the post type is equal to events, and under options set the style to standard.

Advanced Custom Fields location and options screenshot

Now we need to add the functionality that begins the process of separating past events from current/future events. We do this by modifying the pre_get_posts action hook, adding a meta query and creating a $compare variable to compare today’s date with the date selected. At the same time we can also use pre_get_posts to add a limit to the number of posts we want to show per page. This functionality is added to functions.php, as pre_get_posts won’t work if used on template pages.

In our functions.php file we add the following:

/** Customising the custom post type query (comparing today's
 * date with the date selected, and only showing a maximum of 3 posts per page)
 */
function event_post_order( $query ){
    // if this is not an admin screen,
    // and is the event post type archive
    // and is the main query
    if( ! is_admin()
        && $query->is_post_type_archive( 'events' )
        && $query->is_main_query() ){

        // if this is a past events view
        // set compare to before today,
        // otherwise set to today or later
        $compare = isset( $query->query_vars['is_past'] ) ? '<' : '>=';

        // add the meta query and use the $compare var
        $today = date( 'Y-m-d' );
        $meta_query = array( array( 
            'key' => 'event_end_date', // this is the field name for the date picker field
            'value' => $today,
            'compare' => $compare,
            'type' => 'DATE'
        ) );
        // set the meta_query argument to equal the $meta_query array created above
        $query->set( 'meta_query', $meta_query );
        // set the posts per page to 3
        $query->set( 'posts_per_page', '3' );
    }
}
add_action( 'pre_get_posts', 'event_post_order' );

Now for the juicy part. To create a separate page for past events, we need to set up a rewrite tag and a rewrite rule:

//This function creates a page (past) to show all 'events' post types whose end-dates have passed.
function event_archive_rewrites(){

    add_rewrite_tag( '%is_past%','([^&]+)' );
    add_rewrite_rule(
        'events/past/page/([0-9]+)/?$',
        'index.php?post_type=events&paged=$matches[1]&is_past=true',
        'top'
    );
    add_rewrite_rule(
        'events/past/?$',
        'index.php?post_type=events&is_past=true',
        'top'
    );

}
add_action( 'init', 'event_archive_rewrites' );

Looking good! Credit goes to Milo for the basis of the previous two code snippets.

Now for the final touch. In our Genesis theme, the title of our past events page is still showing up as Events – all we’ve done is change the url, so apart from now only showing past events, everything else will be the same. We can easily change that title to Past Events with the following code snippet in functions.php:

function event_archive_url() {
	
	$url = $_SERVER['REQUEST_URI'];

	// if 'events/past' exists in the url, then add text to the beginning of the title
	if (strpos($url,'events/past') !== false) {
   ?>
   <style>
     .archive-title::before {
       content: "Past";
      }
   </style>
   <?php 
   }
 } 

add_action( 'init', 'event_archive_url' );

The end result is a custom events post type with a custom field that will allow users to select an ‘expiry’ date on the event, after which events show on a ‘Past Events’ page, cleanly separating current & future events from past events.

Filed Under: Web development

Custom post types & advanced custom fields in Genesis (part 1)

March 29, 2017 by Karen Attfield Leave a Comment

Setting up the custom post type

I recently found myself needing to create a custom post type as well as being able to split the displayed custom posts into two different blocks of pages. This article walks through that process.

In this article I’ll explain how to set up an events custom post type in WordPress as well as adding meta boxes with the advanced custom fields plugin in order to record event dates and to mark the events as current/future or past. We’ll also look at changing the custom post type output within the Genesis Framework (note: affiliate link). With this information we can then split the events into two separate blocks of pages – one for current/future events, and one for past events.

We’ll start by setting up the custom post type. While you could use a plugin such as Custom Post Type UI  we’ll set the custom post type up manually in a plugin. I prefer this method over putting the code in functions.php as the code is then not linked to the theme if you change your sites theme or redesign it, and you can also easily use it elsewhere. Having said that, any custom post types you create still need to be displayed by your theme, so more than likely you will need to do some modifications theme-side (in functions.php or archive template pages) the more complex your output modifications will be.

We’ll also be defining our plugin within a class. This helps with issues created by functions being thrown into the global namespace, and is considered a superior method of defining a plugin. Tom McFarlin has written an in-depth series about implementing object oriented programming in WordPress if you are interested in finding out more.

You create your custom post plugin by creating a file in your plugins folder, and adding a file (for example custom-posts.php) for the plugin code.

Below is the complete plugin code:

<?php
/*Plugin Name: KA Custom Posts
*Description: This plugin registers the 'events' post type.
*Text Domain: ka-custom-posts
*Version: 1.0
*License: GNU General Public License v2 or later
*License URI: http://www.gnu.org/licenses/gpl-2.0.html 
*/


// Exit if accessed directly
    if ( ! defined( 'ABSPATH' ) ) {
        exit;
    }

    // Check to make sure a class called KA_Custom_Posts doesn't already exist in the global namespace. 
	if ( ! class_exists( 'KA_Custom_Posts' ) ) {

        /**
         * Main Web_Developers_Portfolio class
         */
        // Build the class
        class KA_Custom_Posts {

			// function triggered on initialisation
			public function __construct(){
				add_action( 'init', array($this, 'ka_posts_register'));
			}

			function ka_posts_register() {
					
				// set up labels for Events
				$eventslabels = array(
			 		'name' => 'Events',
			    	'singular_name' => 'Event',
			    	'menu_name' => 'Events',
			    	'new_item' => 'New Event',
			    	'all_items' => 'All Events',
			    	'view_item' => 'View Event',
			    	'search_items' => 'Search Events',
			    	'add_new' => 'Add New Event',
			    	'add_new_item' => 'Add New Event',
			    	'edit_item' => 'Edit Event',
			    	'not_found' =>  'No Events Found',
			    	'not_found_in_trash' => 'No Events found in Trash', 
			    	'ka-custom-posts',
			    );

			    //register post type for Events
				register_post_type( 'event', array(
					'labels' => $eventslabels,
					'has_archive' => true,
			 		'public' => true,
					'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail','page-attributes', 'genesis-seo', 'genesis-cpt-archives-settings'  ),
					'taxonomies' => array( 'post_tag', 'category' ),	
					'exclude_from_search' => false,
					'capability_type' => 'post',
					'rewrite' => array( 'slug' => 'events' ),
					'menu_position' => 20,
					)
				);

			} // end function ka_posts_register
		} // end class KA_Custom_Posts
	} // end beginning if statement


// Check if the class has been defined
if(class_exists('KA_Custom_Posts'))
{
    // instantiate the plugin class
    $wp_plugin_template = new KA_Custom_Posts();
}

I won’t break down the above code as there are many resources on developing custom post types online already. We will look in more detail at integrating the custom fields in order to get the custom event post type to do as we want, as well as modifying the output of the events posts through WordPress actions and filters.

I will however point out the following: if you are using the Genesis Framework you can enable Custom Post Type (CPT) archive settings if you want only a minor level of control over the output, including the ability to add a description to the custom post type page in the same way you would for a normal post (via the Archive Settings link in the WordPress admin dashboard, underneath your custom post type name). You would create an archive template for more complex changes, as described later.

Within your register_post_type() function (and you’ll see this in the code above), you would include support for genesis_cpt_archives-settings, as well as setting several arguments to true:

  •  'has_archive' => true
  •  'public' => true
  •  'show_ui' => true (defaults to true if not added)
  •  'show_in_menu' => true (defaults to true if not added)
  • 'supports' => array( 'title', 'editor', 'genesis-seo', 'thumbnail','genesis-cpt-archives-settings' )

After creating and activating the plugin, you’ll need to reconfigure permalinks in the WordPress dashboard. Make sure post name option is selected. You then create a custom link in your menu – set the address to your-domain.com/events/ (or whatever you have named your custom post type). The posts from that custom post type should then appear on that page, in the same style and format as a normal blog post.

Modifying the output of the custom post type

To modify the output on the front-end, you then create an archive page for the custom post type: archive-events.php. There is no need to copy and paste all the content from archive.php (located in lib/structure under the main genesis theme). Simply add in filters to modify actions to change what is shown on that template page. You can do the same for single archive pages on single-post_type.php. Below is our archive-events.php file with a description of each filter or action (specific to the Genesis Framework) and what it is changing:

<?php
/* 
* Archive Events Template - archive-events.php
*/

//This sets the custom post archive to display the fill content from each post.
add_filter( 'genesis_pre_get_option_content_archive','ka_cp_content_display' );
function ka_cp_content_display() {
 return 'full';
}

//This returns the post thumbnail
add_filter( 'genesis_pre_get_option_content_archive_thumbnail','ka_cp_image_display' );
function ka_cp_image_display() {
 return 1;
}

//Set the image thumbnail size (options: thumbnail, medium, large, and featured-image if defined in your theme)
add_filter( 'genesis_pre_get_option_image_size','ka_cp_image_size' );
function ka_cp_image_size() {
 return 'featured-image';
}

//Changes the image alignment.
add_filter( 'genesis_pre_get_option_image_alignment','ka_cp_image_alignment' );
function ka_cp_image_alignment() {
 return 'aligncenter';
}



// Remove default post title (with link)
remove_action( 'genesis_entry_header','genesis_do_post_title' );


// Function to display the post title without a link
function ka_cp_archive_title() {
	echo '<h2 class="title">' . get_the_title() . '</h2> ';
}

// Add the new post title without a link
add_action( 'genesis_entry_header','ka_cp_archive_title' );


genesis();

We can also modify the output further by removing the entry meta associated with each post (the post author and date). This code needs to go in functions.php, as:

//Remove entry meta for the 'events' post type
function events_remove_entry_meta() {
 	remove_post_type_support( 'events', 'genesis-entry-meta-before-content' );
 	remove_post_type_support( 'events', 'genesis-entry-meta-after-content' );
}
add_action( 'init', 'events_remove_entry_meta', 12 );

In the follow-on article (coming soon) we’ll look at integrating advanced custom fields to our custom post type.

Filed Under: Web development

Dynamic page titles in WordPress using title_tag

December 29, 2016 by Karen Attfield 1 Comment

This article is a follow on from Dynamic page titles in WordPress, where we used wp_title in order to display custom page titles. Since title_tag was introduced in WordPress 4.1, it is now best practice to use this instead of wp_title, which will at some stage be deprecated.

We’ll look at removing wp_title from page titles (through the header’s title tag), and also through dynamically created page titles (for example in h1 / h2 tags on your page).

Adding theme support for title tags

The first step to removing wp_title from the title tag in your WordPress header is by adding theme support in your functions.php file, and then removing the title tag from your header as it is automatically generated. You may also want to add your original custom title code as a fall-back in case the theme you are using does not support title_tag. Here is an example of what the code in your functions.php file should look like:

add_action( 'after_setup_theme', 'yourtheme_setup' );

function yourtheme_setup() {
  add_theme_support( 'title-tag' );
}

/* The below code is a fall-back incase your theme does not support title_tag */
if ( ! function_exists( '_wp_render_title_tag' ) ) :

   function yourtheme_render_title() {
   ?>

   <title>
   // add the original code between your title tags here
   </title>
   <?php
   }
   add_action( 'wp_head', 'yourtheme_render_title' );

endif;

The result you will see will depend on other plugins you are using that also modify the title tag, for example the Yoast SEO plugin. I’ll look at a solution both without plugins, and with Yoast SEO activated.

Customising dynamic titles without Yoast SEO installed

With Yoast SEO not activated, we need to create a custom function (custom_theme_titles) in functions.php. In it, we need to modify the title output by modifying document_title_parts through a filter. In the below example I am modifying the ‘title’ and ‘site’, both parameters within document_title_parts. In order to get the information I need, I am using get_bloginfo() to retrieve the site description and name. In the case of category pages I’m using get_the_category() to retrieve the relevant category, and then pulling out the name as a string with cat_name. I’ve unset $titleparts[‘site’] as leaving it set added my site title to the end of the title, which I didn’t want.

The result of the below code is a page title of ‘Page Name | Sitename – Tagline’ (and just ‘Sitename – Tagline’ on the front-page) that dynamically fills the title tag on every page (including a custom 404 page title, and custom category page titles).

function custom_theme_titles( $titleparts ) {
   if ( is_front_page() ) {
    	$pagetitle = $titleparts['title'];  
        $titleparts['title'] = $pagetitle;
        unset( $titleparts['site'] );
    }
    elseif ( is_404() ) {
    	$pagetitle = "404";
    	$sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );
    }
    elseif (is_category() ) {	
		$category = get_the_category();
		$catName = $category[0]->cat_name;		
		$pagetitle = "Blog - ".$catName." archives";		
    	$sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );
    }   
    else {
  		$pagetitle = $titleparts['title'];
        $sep = " | ";
        $name = get_bloginfo( 'name', 'display' );
        $sep2 = " - ";
        $desc = get_bloginfo( 'description', 'display' );
        $titleparts['title'] = $pagetitle.$sep.$name.$sep2.$desc;
        unset( $titleparts['site'] );   
    }

    return $titleparts;
}
add_filter( 'document_title_parts', 'custom_theme_titles', PHP_INT_MAX );

Customising dynamic titles with Yoast SEO installed

The code snippet to modify titles when Yoast SEO is installed seems a lot simpler, as they have their own filter for the title – wpseo_title. The first step is to define a function that is later passed through the wpseo_filter. First, we set a few variables – a separator, the site name and the site tagline/description. We can then modify the output for different pages, for example returning just the page title (in the default format of ‘Sitename – Tagline’) on the front page (not adding this may result in a duplicate title), custom page title format throughout the site, and also custom individual pages such as a 404 page.

function custom_theme_titles_yoast( $title ) {
    $sep = '|';
    $name = get_bloginfo( 'name' );
    $desc = get_bloginfo( 'description', 'display' );

    if( is_front_page() ) {
        $pagetitle = $title;
        return "{$pagetitle}";
    }
     elseif( is_404() ) {
        $pagetitle = "404";
        return "{$pagetitle} {$sep} {$name} - {$desc}"; 
    }
    else {
        $pagetitle = $title;   
        return "{$pagetitle} {$sep} {$name} - {$desc}";
    }
}
add_filter( 'wpseo_title', 'custom_theme_titles_yoast', PHP_INT_MAX );

If you change the SEO title on any individual page through the Yoast SEO box in the page/post editor, this will alter the title in the title tag for that page (specifically, it will only alter the $title variable in the above code snippet).

Custom on-page titles

Displaying page titles on pages is not too dissimilar to the process shown in the previous article on dynamic page titles, but with a slight change for the wp_title() calls, to use get_the_title() instead. Get_the_title doesn’t work for archive pages as by default it pulls the title of the first post as the page title, so you’ll need separate if statements to cover any archive pages you might use. This code would then go within your header.php file, or wherever you are dynamically adding on-page titles.

<div class="page-title">
			
   <h1> 
	<?php
	if (is_search()) {
		echo "Blog";
	}
	elseif (is_404()) {
		echo "404";
	}
	elseif (is_category()) {
		$category = get_the_category();
		$catName = $category[0]->cat_name;
		$archive_name = "- ".$catName." archives";
		echo "Blog ".$archive_name;
	}
	else {
		echo get_the_title();
	} 
	?>
			 	
   </h1>

</div>

The result should be clean, custom dynamic page titles on your WordPress site, regardless of whether you have Yoast SEO activated or not.

Filed Under: Web development

  • « Previous Page
  • 1
  • 2
  • 3
  • 4
  • Next Page »

Copyright © 2021 · Easeful