Resolving WordPress Twenty Thirteen Disqus Plugin placement issues

WordPress’ new 2013 theme is fantastic, but if you’re also using the Disqus plugin, it’s quite likely you’ve noticed an issue with its placement.

Rather than sitting nicely under the main content, it spreads out and occupies the space visually reserved for the sidebar.

WordPress.org forum thread details some fixes, but I found a quick CSS addition fixed the problem.  Simply add this to the bottom of the 2013 Theme’s stylesheet:

#disqus_thread {
    max-width: 1040px;
    padding: 0 376px 0 60px;
}

This should push the area under the left column and respond appropriately.

I also made a small change to the single.php file, because I feel the ‘post nav’ is better suited to being placed after the comments.  Simply modify the loop of that file to this:

<?php while ( have_posts() ) : the_post(); ?>
  <?php get_template_part( 'content', get_post_format() ); ?>
  <?php comments_template(); ?>
  <?php twentythirteen_post_nav(); ?>
<?php endwhile; ?>

I swapped the order of the comments_template() and twentythirteen_post_nav() function calls.

Hope this helps!

orchard

Orchard Module to Prevent (Indefinite) JS/CSS Caching

A couple of days ago, I saw this tweet

 

A few months ago, I wrote a ‘Resource Timestamper’ Orchard module to add a timestamp to invalidate cache on the client.

Browsers cache resources such as JavaScript and CSS. This is a good thing, but this caching prevents browsers from requesting updated versions of resources. Although doing a ‘hard refresh’ of a page can force a reload of scripts and styles, we can’t expect users to do that to circumvent the problem.

It turns out that resources can be updated using a query string parameter. A client browser considers these as two different requests for the same physical resource:

<link type="text/css" rel="stylesheet" href="somecss.css?1"/>
<link type="text/css" rel="stylesheet" href="somecss.css?2"/>

Using a different query string each time the file is served gets around the caching issue, but loses all benefits of caching.  Better yet, generate a new query string value only when the file has changed.

The Resource Timestamper module modifies resource URLs generated with Orchard’s standard Resource Manager class.  To add a timestamp, call the SetAttribute method with parameters of ‘data-timestamped’, and ‘true’.  Here’s an example from ‘The Theme Machine’s’ Layout.cshtml file:

Style.Include("site.css").SetAttribute("data-timestamped", "true");

On the client, a URL is generated:

http://localhost:30321/OrchardLocal/Themes/TheThemeMachine/styles/site.css?v=635151301095348769

Prior to the timestamp being applied, the URL is converted to an absolute URL.  Why? Well, when writing the module, I realised that trying to append a query string to a relative URL (such as /OrchardLocal/Themes/TheThemeMachine/styles/site.css) didn’t work; the query string was being removed.  I see I’m not the only one who’s noticed Style.Include stripping query strings.

Absolute and relative URLs are often a personal preference, but one issue with absolute URLs is that they must be changed when deploying to a production system, or to another domain.  The plugin uses details of the current request, so there is no need to update the code.

The code generates a timestamp for the resource, and only generates a new timestamp when the file changes in some way.  That way, you get the benefit of caching without the problem of updating the file.

Code Analysis

The single class , FcmResourceManager (Fcm is an abbreviation for my company, Fresh Click Media), derives from Orchard’s ResourceManager class.  To actually use this class, rather than the default ResourceManager, an OrchardSuppressDependency attribute is used:

[OrchardSuppressDependency("Orchard.UI.Resources.ResourceManager")]

The class has a number of Orchard dependencies to get its work done:

private readonly IClock _clock;
private readonly ICacheManager _cacheManager;
private readonly IWebSiteFolder _websiteFolder;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly Work<WorkContext> _workContext;

These members are assigned using constructor injection.

The crucial method override is called BuildRequiredResources:

public override IList<ResourceRequiredContext> BuildRequiredResources(string stringResourceType)
{
    var resources = new List<ResourceRequiredContext> base.BuildRequiredResources(stringResourceType));
    foreach (var resource in resources)
    {
        if (resource.Settings.Attributes == null)
            continue;
        if ((from a in resource.Settings.Attributes.ToList()
            where a.Key == "data-timestamped"
            select a).Any())
        {
            resource.Resource.SetUrl(GetCachedUrl(resource));
        }
    }
    return resources;
}

It is this method that is called, and gives us an opportunity to manually set the new URL for the given resource.  This is only done is the ‘data-timestamped’ attribute is found.  In this scenario, the GetCachedUrl method is called.

The GetCachedUrl is shown below:

private string GetCachedUrl(ResourceRequiredContext resource)
{
    if (resource.Resource.Url.StartsWith("http://") || resource.Resource.Url.StartsWith("https://"))
    {
        return resource.Resource.Url;
    }
    string path = GetResourcePath(resource);
    // it's a local file:
    return _cacheManager.Get("Fcm.ResourceCache." + path, ctx =>
    {
        ctx.Monitor(_websiteFolder.WhenPathChanges(path));
        return GetUpdatedUrl(path);
    });
}

The method ignores absolute URLs.  For relative URLs, the path of the file is ascertained.  Orchard’s ICacheManager returns the value of GetUpdatedUrl(…) for a cache key made up of a combination of ‘Fcm.ResourceCache’ and the file’s path.  The cache is invalidated when the path of the file changes.  In this situation the path changes when the file is updated.

The GetUpdatedUrl method takes the original path of the resource, and converts to an absolute URL.

Download and Install

Once you download the module, you can install in the usual way.  The usual way? Go here for more information about installing Orchard modules.

Once the module has been installed, you should see a reassuring message as shown below.  Enable the ‘Resource Timestamper’ feature.

resource timestamper install

One final thing

I hope you find the module useful.  It was written for Orchard 1.5, but has been tested on Orchard 1.7.1 (latest at the time of writing).  It shouldn’t cause you any issues, but you should test it fully on a local environment before deploying it to a production environment. Think that covers it.

Redis

Installing Redis on Windows

Getting started with Redis on Windows is easy:

1. Download the latest .exe package from https://github.com/rgl/redis/downloads (choose the appropriate latest 32 or 64 bit version).

2. Running the exe will install Redis as a service and install the Redis client.

Troubleshooting

I got an issue when installing the service through the setup.  I had to do so manually using this command (ensure that you run cmd as Administrator):

sc create redis binPath= "C:\Program Files\Redis\redis-service.exe redis conf/redis.conf"

Note that Windows is particularly fussy about the space after binPath=, and paths with spaces must be wrapped with quotes.

Have fun!