Wordpress – Chris Gilligan » new media https://chrisgilligan.com portfolio of web work Wed, 10 Jul 2019 22:12:16 -0400 en-US hourly 1 https://wordpress.org/?v=5.3 Responsive and Accessible Charts and Graphs https://chrisgilligan.com/portfolio/responsive-accessible-charts-graphs/ https://chrisgilligan.com/portfolio/responsive-accessible-charts-graphs/#respond Wed, 15 Mar 2017 13:24:55 +0000 https://chrisgilligan.com/?p=2429 I have been looking for a simple solution to create and manage “dashboard” type charts on a website. Something that would produce editable graphs, accessible content for screen readers, and fit into a responsive design. Chartist.js is a simple and independent library to create SVG charts in the DOM. Various plugins are available to extend […]

The post Responsive and Accessible Charts and Graphs appeared first on Chris Gilligan » new media.

]]>

I have been looking for a simple solution to create and manage “dashboard” type charts on a website. Something that would produce editable graphs, accessible content for screen readers, and fit into a responsive design.

Chartist.js is a simple and independent library to create SVG charts in the DOM. Various plugins are available to extend the functionality and display options. In this example, the accessibility and axis label plugins are used. There are also plugins available for frameworks, and for WordPress (as a TablePress plugin extension).

It makes a responsive chart, with an optional accessible table (hidden by default, but displayed on this example, to show the values).
Check out the CodePen attached to this post. You can interact with the chart by clicking on the legend labels to toggle the series on/off.
After a chart is set up, the only values a user would need to modify are the data variables at the top of the JS: labels and series. If the y-axis series values change, they would have to modify axisY values for ticks, high/low. The remainder of the JS is display parameters and accessibility options.

See the Pen Chartist Graph with (visible) accessibility, point label, legend and axis label plugins: CCTN by utcwebdev (@utcwebdev) on CodePen.dark

 

The post Responsive and Accessible Charts and Graphs appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/portfolio/responsive-accessible-charts-graphs/feed/ 0
Integrating Content from External Sources into OU Campus Using RSS, PHP, and JavaScript https://chrisgilligan.com/consulting/integrating-content-from-external-sources-into-ou-campus-using-rss-php-and-javascript/ https://chrisgilligan.com/consulting/integrating-content-from-external-sources-into-ou-campus-using-rss-php-and-javascript/#respond Tue, 23 Feb 2016 00:50:35 +0000 https://chrisgilligan.com/?p=2386 The web team of the University of Tennessee at Chattanooga uses PHP and RSS to syndicate blog content, news releases, and calendar events into their main website. PHP SimpleXML is used to parse the XML of the RSS feeds. We import a variety of feeds, from WordPress, from Master Calendar, and from other sites such as […]

The post Integrating Content from External Sources into OU Campus Using RSS, PHP, and JavaScript appeared first on Chris Gilligan » new media.

]]>

The web team of the University of Tennessee at Chattanooga uses PHP and RSS to syndicate blog content, news releases, and calendar events into their main website.

PHP SimpleXML is used to parse the XML of the RSS feeds. We import a variety of feeds, from WordPress, from Master Calendar, and from other sites such as an external athletics CMS. WordPress provides some RSS features, including RSS from categories, tags and search strings, but we have added media attachments and a customized template to output a more complicated RSS feed on the University home page.

News releases, events and content from WordPress via RSS

Example web pages:

WordPress plugin & PHP to add media attachments to RSS feed

Example RSS feeds (view XML/XSL styled page in FireFox; View Source to see XML structure, namespaces, node names and structure):

Custom WordPress RSS feed template, followed by the functions call to load and create it:

<?php
/*
Template Name: Custom Current Headlines Feed

*/

$numposts = 10;
$category_id = get_cat_ID('Current Headlines');

function custom_rss_date( $timestamp = null ) {
  $timestamp = ($timestamp==null) ? time() : $timestamp;
  echo date(DATE_RSS, $timestamp);
}

function custom_rss_text_limit($string, $length, $replacer = '&hellip;') { 
  $string = strip_tags($string);
  if(strlen($string) > $length) 
    return (preg_match('/^(.*)\W.*$/', substr($string, 0, $length+1), $matches) ? $matches[1] : substr($string, 0, $length)) . $replacer;   
  return $string; 
}

$posts = query_posts('cat='.$category_id.'&showposts='.$numposts);

$lastpost = $numposts - 1;



header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
$more = 1;

echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>

<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	<?php do_action('rss2_ns'); ?>
>

<channel>
	<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
	<atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
	<link><?php bloginfo_rss('url') ?></link>
	<description><?php bloginfo_rss("description") ?></description>
	<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
	<language><?php bloginfo_rss( 'language' ); ?></language>
	<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
	<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
	<?php do_action('rss2_head'); ?>
	<?php while( have_posts()) : the_post(); ?>
	<item>
		<title><?php the_title_rss() ?></title>
		<link><?php the_permalink_rss() ?></link>
		<comments><?php comments_link_feed(); ?></comments>
		<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
		<dc:creator><?php the_author() ?></dc:creator>
<?php the_category_rss('rss2') ?>
		<guid isPermaLink="false"><?php the_guid(); ?></guid>
<?php if (get_option('rss_use_excerpt')) : ?>
		<description><![CDATA[<?php get_the_excerpt(); ?>]]></description>
<?php else : ?>
		<description><?php echo '<![CDATA['.custom_rss_text_limit($post->post_content, 256).']]>';  ?></description>
<?php $content = get_the_content_feed('rss2'); ?>
	<?php if ( strlen( $content ) > 0 ) : ?>
		<content:encoded><![CDATA[<?php echo $content; ?>]]></content:encoded>
	<?php else : ?>
		<content:encoded><![CDATA[<?php the_excerpt(); ?>]]></content:encoded>
	<?php endif; ?>
<?php endif; ?>
		<wfw:commentRss><?php echo esc_url( get_post_comments_feed_link(null, 'rss2') ); ?></wfw:commentRss>
		<slash:comments><?php echo get_comments_number(); ?></slash:comments>
<?php rss_enclosure(); ?>
<?php do_action('rss2_item'); ?>
		</item>
	<?php endwhile; ?>
</channel>
</rss>
/* Custom RSS Feed for Home Page headlines */

function create_my_customfeed() {
load_template( get_stylesheet_directory() . '/headlines-customfeed.php');
}
add_action('do_feed_headlines', 'create_my_customfeed', 10, 1);

OU Campus PHP helper file and code asset

To parse an existing external RSS feed, such as a standard or custom WordPress feed, we use a helper file that employs PHP’s simplexml_load_string to load the targeted RSS feed, traverse the XML document, select node content, then echo out a block of styled html for each set of targeted XML nodes. The helper file accepts the $feed variable to specify the location of the targeted feed, and the $maxitems variable to specify the number of items to select from the top of the that feed.

On its own, the PHP helper file can be hit in a browser, to verify the targeted feed type exists and is parsed correctly. The browser will return an un-styled html page from the helper file URL.

The OU Campus Code Asset includes the helper file, over-rides the helper’s default variables, is and is very simple to copy and modify, according to the intended target feed and desired number of items to be presented on the final page. Many different Assets can include a single helper file.

(Vinit from OmniUpdate outlined a much better way to handle the feed URL and number of items in his Server Side Scripting class: via PCF Page Parameters.)

PHP file

  • parses feed and displays HTML
    • variables set to defaults for testing
      • may need to verify feed access and XML structure
  • various types of display html
    • title, excerpt, thumbnail from WordPress
    • title only from WordPress
    • RSS feed with formatting or namespaces different from WordPress
<?php

$input = $_SERVER['QUERY_STRING'];
parse_str($input);

if (!isset($feed))//script or page property will choose which feed to display
	$feed = "http://blog.utc.edu/news/headlines.xml/";

if(!isset($maxitems))
	$maxitems = 3;

$file = file_get_contents($feed);
$file = str_ireplace('src="http://', 'src="//', $file);
$file = str_ireplace('media:content url="http://', 'media:content url="//', $file);
$file = str_ireplace('media:thumbnail url="http://', 'media:thumbnail url="//', $file);

$sxml = simplexml_load_string($file);

$i = 0;
	foreach ($sxml->channel->item as $item) {
		if (++$i > $maxitems) {
				break;
			}
		$namespaces      = $item->getNameSpaces( true );
		$content         = isset($namespaces['content']) ? $item->children( $namespaces['content'] ) : '';
		$content_encoded = isset($content->encoded)      ? $content->encoded                         : '';
		$media           = isset($namespaces['media'])   ? $item->children( $namespaces['media'] )   : '';
		$html       = "<div class=\"row-fluid\">"
					.     "<h3><a href=\"{$item->link}\">{$item->title}</a></h3>"
					.     "{$content_encoded}"
					.  "</div>";
	echo($html);
}
?>
<script>
	$(document).ready(function(){
		$('.sidebar img').removeClass().addClass('thumbnail pull-right span5');
		$('aside.well img').removeClass().addClass('thumbnail pull-right span5');
	});
</script>

OU Campus Assets

  • simple structure
    • specify RSS source
    • number of posts to display
<?php
$feed = "//blog.utc.edu/hr/category/benefits/feed/";
include($_SERVER['DOCUMENT_ROOT']. '/_resources/php/get-headlines-sidebar.php');
$maxitems = 5;
?>

(Vinit from OmniUpdate outlined a much better way to handle the feed URL and number of items in his Server Side Scripting class: via PCF Page Parameters.)

More Speed

After you verify the final production page, you should set up cron jobs for any external feeds that are created via database calls on the external servers. A WordPress feed will require a bit of PHP and MySQL work to generate the RSS feed. This requires some processing, and will introduce a delay in service of the OU Campus PHP page. To avoid this latency, we create cron jobs on the production server to periodically fetch the feeds and cache them locally on the production server. The speed increase for the final page product is noticeable.

If your OU Campus Sites include development, test, training, or mobile Sites, you will want to duplicate the local static feeds on all of the OU Sites.

If you control an external WordPress site, you can employ caching mechanisms or plugins to more efficiently serve RSS feeds.

  • cache RSS feeds via WordPress plugin, e.g. W3  Total Cache
  • cron job to fetch feeds to local production servers
  • minimize external requests for faster page load

This cron job can be placed in /etc/cron.hourly to fetch WordPress feeds, check lastBuildDate, and compare that to the existing build date, and create a cached RSS xml file.

#!/bin/bash

# Preload WordPress Feeds for Website

# UTC News
wget http://blog.utc.edu/news/headlines.xml/ -O /data/web/prod/www/_resources/rss/wp-news.tmp >/dev/null 2>&1
TMP_LASTBUILD="$(xml_grep '/rss/channel/lastBuildDate' --text_only /data/web/prod/www/_resources/rss/wp-news.tmp)"
XML_LASTBUILD="$(xml_grep '/rss/channel/lastBuildDate' --text_only /data/web/prod/www/_resources/rss/wp-news.xml)"
MIMETYPE=`file -b --mime-type /data/web/prod/www/_resources/rss/wp-news.tmp`
if [ "$MIMETYPE" == "application/xml" -a  "$TMP_LASTBUILD" != "$XML_LASTBUILD" ] ; then
    mv /data/web/prod/www/_resources/rss/wp-news.tmp /data/web/prod/www/_resources/rss/wp-news.xml
fi

# Duplicate for development, test & training environments
cp -p /data/web/prod/www/_resources/rss/wp*.xml /data/web/test/www/_resources/rss/
cp -p /data/web/prod/www/_resources/rss/wp*.xml /data/web/test/train/_resources/rss/
cp -p /data/web/prod/www/_resources/rss/wp*.xml /data/web/dev/www/_resources/rss/

For other RSS sources, the structure may be different; maybe we can’t do a lastBuildDate check. And… some servers may not respond to a default wget request from a shell script. No problem: just specify --header and --user-agent, don’t do the lastBuildDate check, and just write the RSS XML file.

#!/bin/bash

# Preload GoMocs Feeds for Website


# Gomocs.com News
wget  --header="Accept: text/html" --user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0" http://www.gomocs.com/rss.aspx -O /data/web/prod/www/_resources/gomocs-news.xml

# Duplicate for development, test & training environments
cp -p /data/web/prod/www/_resources/rss/gomocs*.xml /data/web/test/www/_resources/rss/
cp -p /data/web/prod/www/_resources/rss/gomocs*.xml /data/web/test/train/_resources/rss/
cp -p /data/web/prod/www/_resources/rss/gomocs*.xml /data/web/dev/www/_resources/rss/

Event Calendar RSS feeds from Master Calendar via RSS

Example pages that include feeds from Master Calendar. MC has a very rudimentary RSS output of title, date/time and description. MC caches its RSS feeds by default, and expects a lot of traffic to the feed locations, so it is not so necessary to create cron jobs to fetch them. However, if you have an OU Campus page that fetches and displays a large number of MC feeds, you will see a performance increase by using cron jobs. UTC.edu’s home page fetches a number of feeds, and we saw a noticeably faster page load after moving these calls to cron jobs.

Social Media Streams

UTC uses a jQuery plugin and PHP to pull in social media posts for the university account, as well as for individual departments and colleges. This is an easy way to create a social stream sidebar or social wall page.

Facebook, Twitter and Instagram require PHP  API script for connection to signed apps. jquery.imagesloaded is helpful for the wall display

Code Samples

(A compilation zip including all code mentioned in the presentation is available. Comment and subscribe to this post to be notified of updates.)

  • WordPress plugin to add media attachments to RSS feed
  • WordPress functions.php changes
  • PHP files to parse feeds and display HTML
  • OU Campus Assets to specify RSS source and set number of posts
  • cron job to fetch RSS feeds to local server

The post Integrating Content from External Sources into OU Campus Using RSS, PHP, and JavaScript appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/consulting/integrating-content-from-external-sources-into-ou-campus-using-rss-php-and-javascript/feed/ 0
TEDx Event Website https://chrisgilligan.com/portfolio/tedx-event-website/ https://chrisgilligan.com/portfolio/tedx-event-website/#respond Wed, 04 Nov 2015 17:13:14 +0000 https://chrisgilligan.com/?p=2342 I’m very excited to help out with Chattanooga’s premier TEDx event: TEDxChattanooga. For this site, I chose a responsive Bootstrap 3 SASS WordPress theme, originally developed for TEDxToronto. I made a few tweaks and improvements to better fit our event, and worked with April Cox from UT Chattanooga to dial in the design and architecture. Developed on […]

The post TEDx Event Website appeared first on Chris Gilligan » new media.

]]>

I’m very excited to help out with Chattanooga’s premier TEDx event: TEDxChattanooga.

TEDxChattanooga website screenshot

TEDxChattanooga website

screen-shot 2015-11-04 at 11.51.25 AMFor this site, I chose a responsive Bootstrap 3 SASS WordPress theme, originally developed for TEDxToronto. I made a few tweaks and improvements to better fit our event, and worked with April Cox from UT Chattanooga to dial in the design and architecture. Developed on an Amazon EC2+Ubuntu+Webmin server running a Nginx+MySQL+PHP-FPM stack, the site should handle plenty of traffic, and can be scaled up to meet spikes in demand coinciding with the event.

Please check out TEDxChattanooga.com!

Love Open Source software, but hate the generic branding? No problem. It’s very simple to create a fully-branded login screen for WordPress and Webmin/Virtualmin, to match a client’s logo and color scheme.


 

screen-shot 2015-11-04 at 11.49.19 AM

screen-shot 2015-11-04 at 12.06.49 PM

screen-shot 2015-11-04 at 12.09.52 PM

The post TEDx Event Website appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/portfolio/tedx-event-website/feed/ 0
Land Trust Website with Events Calendar https://chrisgilligan.com/portfolio/land-trust-website-with-events-calendar/ https://chrisgilligan.com/portfolio/land-trust-website-with-events-calendar/#respond Wed, 14 Aug 2013 20:44:39 +0000 https://chrisgilligan.com/?p=2043 Lula Lake Land Trust needed a quick website update to replace a neglected site that had been dormant for years. I chose WordPress with a Bootstrap theme for quick and flexible development, and generated a color palette using the Lavish Bootstrap color scheme generator. This is a great example of a site that can come […]

The post Land Trust Website with Events Calendar appeared first on Chris Gilligan » new media.

]]>

Lula Lake Land Trust needed a quick website update to replace a neglected site that had been dormant for years. I chose WordPress with a Bootstrap theme for quick and flexible development, and generated a color palette using the Lavish Bootstrap color scheme generator.

This is a great example of a site that can come together in mere days, look great, and function well on every device from desktop to tablet to smart phone.

Lula Lake Land Trust website

Lula Lake Land Trust website

screen-shot 2013-08-14 at 4.47.54 PM

The post Land Trust Website with Events Calendar appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/portfolio/land-trust-website-with-events-calendar/feed/ 0
University Website and Blog Redesign https://chrisgilligan.com/portfolio/university-website-and-blog-redesign/ https://chrisgilligan.com/portfolio/university-website-and-blog-redesign/#respond Wed, 14 Aug 2013 18:03:46 +0000 https://chrisgilligan.com/?p=2038 This was a team project for the University of Tennessee at Chattanooga, my alma mater and current employer. I was hired by UTC as web development specialist in late 2012, and worked with a cross-discipline team on the redesign, information architecture, 10,000 page migration to CMS and user training for over 300 web editors. The […]

The post University Website and Blog Redesign appeared first on Chris Gilligan » new media.

]]>

This was a team project for the University of Tennessee at Chattanooga, my alma mater and current employer. I was hired by UTC as web development specialist in late 2012, and worked with a cross-discipline team on the redesign, information architecture, 10,000 page migration to CMS and user training for over 300 web editors.

The design was built on Bootstrap, a versatile framework that includes a flexible, responsive grid system, icon font, and LESS/CSS styling for nearly any imaginable UI element. The site looks great on desktop, tablet and mobile phone; images are resized according to users’ maximum screen width by Adaptive Images.

utc-edu-bootstrap-site

We worked with OmniUpdate to port the functional HTML templates to the OU Campus Content Management System.

A companion WordPress theme was created to retrofit the UTC Blogs MultiSite. Enhanced WordPress RSS feeds in the media namespace populate news feeds on the home page.

Deets for Devs

We’re using Bootstrap 2.3.2 with Font Awesome 3.2.1 icons.

For initial HTML development, I used  Kickstrap.

I found a lot of great examples and code at  WrapBootstrap and Bootsnip.

Our custom CSS files work for both the OU Campus site and WordPress blogs, because templates for both are built on Bootstrap… on WordPress, we use a child theme with a  BootSwatch style custom CSS.

We host our own CSS, but pull fonts and JavaScript libraries from CDNs. Off-Canvas, drop-down sidenav was custom built using Bootstrap components, but now Jasny’s Bootstrap 3.0 fork (jasny.github.io/bootstrap) has a similar extension.

LESS Files: along with the entire development site (was easier to zip this way). Download & unzip, it will run as a local site if you like…

Start with kickstrap.less, see what it includes — mostly the standard Bootstrap LESS files. Next look at theme.less, which jumps to Kickstrap/themes/utcms/theme.less, which has all of the custom stuff and some comments. Read the comments and then look at the individual files to see what’s going on: basically, anything that’s commented out uses the base Bootstrap CSS. At some point, I would like to change this workflow to pull the standard Bootstrap CSS from a CDN, and only load the override CSS.

Most of our specific changes are in variables.less, navbar.less, main.less (final custom overrides and tweaks) and logotype.less (for the header). I used CODA as an IDE, with CodeKit as my LESS compiler.

The post University Website and Blog Redesign appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/portfolio/university-website-and-blog-redesign/feed/ 0
WordPress Fail2Ban RegEx for RedHat, CentOS, Amazon Linux https://chrisgilligan.com/consulting/wordpress-wp-fail2ban-regex-redhat-centos-amazon-linux/ https://chrisgilligan.com/consulting/wordpress-wp-fail2ban-regex-redhat-centos-amazon-linux/#respond Thu, 30 May 2013 00:30:24 +0000 https://chrisgilligan.com/?p=1875 VacantServer WordPress sites are getting hammered with bad logins and probes. We’ve implemented a plugin to log failed login attempts to syslog, and a Fail2Ban filter for the same. If you run these on RedHat, you’ll need some additional configuration info… here it is: WordPress login failure regex (error_log): ^%(__prefix_line)sAuthentication failure for .* from <HOST>$ […]

The post WordPress Fail2Ban RegEx for RedHat, CentOS, Amazon Linux appeared first on Chris Gilligan » new media.

]]>
VacantServer WordPress sites are getting hammered with bad logins and probes.

We’ve implemented a plugin to log failed login attempts to syslog, and a Fail2Ban filter for the same. If you run these on RedHat, you’ll need some additional configuration info… here it is:

WordPress login failure regex (error_log):
^%(__prefix_line)sAuthentication failure for .* from <HOST>$

Apache nohome regex (error_log):

[[]client <HOST>[]] File does not exist: .*/~.*

PHP noscript regex (/home/*/logs/error_log,/var/log/httpd/error_log):

[[]client <HOST>[]] (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)
[[]client <HOST>[]] script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat *$

XMLRPC flood attacks — DDoS and probing (/home/*/logs/access_log):

<HOST>\s.*\s.POST\s/xmlrpc.php*.\s.*

Please also enable the generic apache-nohome, apache-noscript. Install wp fail2ban plugin (and configure it for your server) on your high traffic blogs. These all are helping during the current onslaught, which also includes probing for wp-admin directories, probing for /wp-admin/login.php, plus comment spam.

A new XMLRPC exploit has the script kiddies doing DDoS and probing for vulnerable services, and possibly doing remote code execution on vulnerable services.

Here are some additional resources:

The post WordPress Fail2Ban RegEx for RedHat, CentOS, Amazon Linux appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/consulting/wordpress-wp-fail2ban-regex-redhat-centos-amazon-linux/feed/ 0
SSL and CloudFront CDN Support for WebFonts via .htaccess https://chrisgilligan.com/wordpress/add-cloudfront-cdn-support-for-webfonts-via-htaccess/ https://chrisgilligan.com/wordpress/add-cloudfront-cdn-support-for-webfonts-via-htaccess/#comments Wed, 05 Sep 2012 21:33:27 +0000 https://chrisgilligan.com/?p=1005 I recently upgraded my WordPress theme to WooThemes Canvas 5.x, and I found that some of the icons were not rendering, but were showing a letter or integer instead. I dug into the code and found that these icons are now delivered via @font-face webfonts. Meanwhile, I’m working on a client’s e-commerce site with Google […]

The post SSL and CloudFront CDN Support for WebFonts via .htaccess appeared first on Chris Gilligan » new media.

]]>

I recently upgraded my WordPress theme to WooThemes Canvas 5.x, and I found that some of the icons were not rendering, but were showing a letter or integer instead. I dug into the code and found that these icons are now delivered via @font-face webfonts.

Meanwhile, I’m working on a client’s e-commerce site with Google WebFonts and a custom webfont to display the Rupee symbol (Indian currency).

Though the fonts were uploading properly to the CloudFront CDN, and were properly referenced in the minified CSS on the CDN, they were not rendering in Firefox or IE, and the SSL pages on the client’s site were throwing security warnings.

At first I thought this might be a W3 Total Cache issue, because upgrading to the latest development release had solved some other CSS issues. However, it turned out to be a browser security issue.

Evidently this is a security measure to prevent cross-site attacks, but you can allow this via Apache mod_headers, to allow your specific CloudFront (or other) domain, specified in the .htaccess file.

Some sites have suggested using “*” wildcards to allow all domains… but obviously this is a security issue: with this Header, you are granting JavaScript clients basic access to your resources. I recommend you only allow access to the specific CDN domains you require. Do this with a comma separated list, in double quotes.

# BEGIN CDN Cross-Site for Webfonts
<IfModule mod_mime.c>
        AddType font/ttf .ttf
        AddType font/eot .eot
        AddType font/opentype .otf
        AddType font/x-woff .woff
</IfModule>
<FilesMatch "\.(svg|ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "fonts.googleapis.com,{{yourdistro69}}.cloudfront.net"
    </IfModule>
</FilesMatch>
# END CDN Cross-Site for Webfonts

Yay! Delicious webfonts, even on SSL pages via CDN!

The post SSL and CloudFront CDN Support for WebFonts via .htaccess appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/wordpress/add-cloudfront-cdn-support-for-webfonts-via-htaccess/feed/ 2
Varnish VCL and Config for WordPress with W3 Total Cache https://chrisgilligan.com/consulting/varnish-vcl-and-config-for-wordpress-with-w3-total-cache/ https://chrisgilligan.com/consulting/varnish-vcl-and-config-for-wordpress-with-w3-total-cache/#comments Wed, 15 Aug 2012 00:23:11 +0000 https://chrisgilligan.com/?p=867 I have been working on a Varnish front-end for Apache, to be used with WordPress sites. I described the architecture in Load Balancing Virtualmin WordPress Hosting Server with Varnish on AWS. I now have a configuration that seems to work for all WordPress features, including logged-out commenting. This configuration also works well with W3 Total […]

The post Varnish VCL and Config for WordPress with W3 Total Cache appeared first on Chris Gilligan » new media.

]]>

I have been working on a Varnish front-end for Apache, to be used with WordPress sites. I described the architecture in Load Balancing Virtualmin WordPress Hosting Server with Varnish on AWS. I now have a configuration that seems to work for all WordPress features, including logged-out commenting. This configuration also works well with W3 Total Cache.

This configuration is for Varnish on a separate server, but should also work on a single server with appropriate changes to the port and backend IP settings.

Varnish Config (/etc/sysconfig/varnish)

# Configuration file for varnish
#
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
#
#
# Maximum number of open files (for ulimit -n)
NFILES=131072
#
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=82000
#
# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
# DAEMON_COREFILE_LIMIT="unlimited"
#
# Set this to 1 to make init script reload try to switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE
RELOAD_VCL=1
#
## Advanced configuration
#
# # Main configuration file.
VARNISH_VCL_CONF=/etc/varnish/wordpress-varnish3.vcl
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=80
#
# # Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#
# # Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret
#
# # The minimum number of worker threads to start
VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location if using file cache
#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin
#
# # Cache size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=3G
#
# # Backend storage specification
# malloc runs from RAM, file from file
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script. If you add or remove options,
# # be sure you update this section, too.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-t ${VARNISH_TTL} \
-w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
-u varnish -g varnish \
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE}"
#

Varnish VCL (/etc/varnish/wordpress-varnish3.vcl)

backend origin {
.host = "10.11.12.13";
.port = "80";
.connect_timeout = 60s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 60s;
}
#
sub vcl_recv {
# only using one backend
set req.backend = origin;
#
# set standard proxied ip header for getting original remote address
set req.http.X-Forwarded-For = client.ip;
#
# logged in users must always pass
if( req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_" ){
return (pass);
}
# accept purges from w3tc and varnish http purge
if (req.request == "PURGE") {
return (lookup);
}
#
# don't cache search results
if( req.url ~ "\?s=" ){
return (pass);
}
#
# always pass through posted requests and those with basic auth
if ( req.request == "POST" || req.http.Authorization ) {
return (pass);
}
#
# else ok to fetch a cached page
unset req.http.Cookie;
return (lookup);
}
#
# accept purges from w3tc and varnish http purge
sub vcl_hit {
if (req.request == "PURGE") { purge; }
return (deliver);
}
#
# accept purges from w3tc and varnish http purge
sub vcl_miss {
if (req.request == "PURGE") { purge; }
return (fetch);
}
#
sub vcl_fetch {
#
# remove some headers we never want to see
unset beresp.http.Server;
unset beresp.http.X-Powered-By;
#
# only allow cookies to be set if we're in admin area - i.e. commenters stay logged out
if( beresp.http.Set-Cookie && req.url !~ "^/wp-(login|admin)" ){
unset beresp.http.Set-Cookie;
}
#
# don't cache response to posted requests or those with basic auth
if ( req.request == "POST" || req.http.Authorization ) {
return (hit_for_pass);
}
#
# only cache status ok
if ( beresp.status != 200 ) {
return (hit_for_pass);
}
#
# don't cache search results
if( req.url ~ "\?s=" ){
return (hit_for_pass);
}
#
# else ok to cache the response
set beresp.ttl = 24h;
return (deliver);
}
#
sub vcl_deliver {
# add debugging headers, so we can see what's cached
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
}
else {
set resp.http.X-Cache = "MISS";
}
# remove some headers added by varnish
unset resp.http.Via;
unset resp.http.X-Varnish;
}
#
sub vcl_hash {
hash_data( req.url );
# altering hash so subdomains are ignored.
# don't do this if you actually run different sites on different subdomains
if ( req.http.host ) {
hash_data( regsub( req.http.host, "^([^\.]+\.)+([a-z]+)$", "\1\2" ) );
} else {
hash_data( server.ip );
}
# ensure separate cache for mobile clients (WPTouch workaround)
if( req.http.User-Agent ~ "(iPod|iPhone|incognito|webmate|dream|CUPCAKE|WebOS|blackberry9\d\d\d)" ){
hash_data("touch");
}
return (hash);
}

The post Varnish VCL and Config for WordPress with W3 Total Cache appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/consulting/varnish-vcl-and-config-for-wordpress-with-w3-total-cache/feed/ 25
Punk Rock Music Community https://chrisgilligan.com/portfolio/punk-rock-music-community/ https://chrisgilligan.com/portfolio/punk-rock-music-community/#respond Tue, 10 Apr 2012 14:20:41 +0000 https://chrisgilligan.com/?p=771 Punktastic.com is a community powered site that covers punk music in Britain, but is poised to go worldwide. They cover punk and hardcore shows and festivals, and provide album reviews, video interviews and more. With a growing audience and user base, Punktastic needed a more reliable and robust web server, so they made the move […]

The post Punk Rock Music Community appeared first on Chris Gilligan » new media.

]]>

Punktastic.com is a community powered site that covers punk music in Britain, but is poised to go worldwide. They cover punk and hardcore shows and festivals, and provide album reviews, video interviews and more.

With a growing audience and user base, Punktastic needed a more reliable and robust web server, so they made the move to a dedicated CentOS 5 series web server with 3GB RAM. While this is a relatively low-end box, it has plenty of horsepower for a single WordPress site and phpBB3 forum.

Punktastic.com web site

For this GIG, I soloed on…

  • transferring the site from a WAMP development server to the live LAMP server
  • configuring an active firewall to block the baddies
  • installing monitoring and administration tools
  • tuning Apache and MySQL for high traffic
  • integrating APC PHP Cache to speed up web pages and provide better concurrency

Loud Fast Rules.

The post Punk Rock Music Community appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/portfolio/punk-rock-music-community/feed/ 0
WordPress with W3 Total Cache on Nginx with APC (Virtualmin) https://chrisgilligan.com/wordpress/wordpress-with-w3-total-cache-on-nginx-with-apc-virtualmin/ https://chrisgilligan.com/wordpress/wordpress-with-w3-total-cache-on-nginx-with-apc-virtualmin/#comments Mon, 12 Mar 2012 15:25:34 +0000 https://chrisgilligan.com/?p=672 Virtualmin now includes support for Nginx web server. I deploy many WordPress sites with W3 Total Cache and APC Alternative PHP Cache, so I was very interested to see how Nginx performance compares to Apache for WordPress, and whether APC and W3TC would play nice with Nginx. I prefer to install WordPress in public_html/wordpress for […]

The post WordPress with W3 Total Cache on Nginx with APC (Virtualmin) appeared first on Chris Gilligan » new media.

]]>

Virtualmin now includes support for Nginx web server. I deploy many WordPress sites with W3 Total Cache and APC Alternative PHP Cache, so I was very interested to see how Nginx performance compares to Apache for WordPress, and whether APC and W3TC would play nice with Nginx.

I prefer to install WordPress in public_html/wordpress for ease of development, compatibility with other scripts, etc. Accordingly, the suggested configuration is for WordPress installed in a subfolder. This info also assumes you have successfully installed APC Cache on your server, and set up a clean install of Virtualmin with Nginx as the Alternative Web Server. Switching from Apache to Nginx later is difficult, as is transferring apache virtual server backups. Best to start fresh and build from scratch.

Testing the Virtualmin Nginx Modules

Virtualmin does not support Nginx and Apache together, and there is no easy migration from Apache to Nginx, so it is suggested to begin with a fresh install of Virtualmin with no existing accounts.

If you would like to experiment with Nginx, and you already have a Virtualmin Pro license, you are permitted to set up Virtualmin on a second server for testing and migration. I run the extra Virtualmin Pro system on a VPS that I use for backups, slave DNS, and testing.

The Nginx modules are also available for the free Virtualmin GPL version. To install the modules, go to Virtualmin Package Updates (wbm-virtualmin-nginx and wbm-virtualmin-nginx-ssl).

WordPress Plugins for this Setup

  • W3 Total Cache — adds opcode cache, minification, browser cache and page cache capabilities to WordPress… and it works with Nginx. Works best with Alternative PHP Cache to provide opcode and database cache. Setting APC for all caches works easiest with Nginx… setting to file caching introduces URL rewrite errors… See W3TC Settings information below for instructions on how to implement File caching.
  • nginx Compatibility — makes WordPress more compatible with Nginx, allows use of permalinks without /index.php/

Configuring Nginx for WordPress pretty URL Permalinks

The nginx Compatibility plugin has support for pretty URLs, but you must configure Nginx to use them. You should add or edit the following URL path locations to nginx.conf for your virtual domain… either by direct edit, or via URL Path Locations in Virtualmin > Services > Configure Nginx Website (see attached image…). This config is for WP installed in /public_html/wordpress, so you will need to omit or change /wordpress if WP is installed in a different directory.

location ^~ /files/ {
rewrite /files/(.+) /wordpress/wp-includes/ms-files.php?file=$1 last;
}
location @wordpress {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_NAME /index.php;
}
location ~ \.php$ {
try_files $uri @wordpress;
fastcgi_index index.php;
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ^~ /blogs.dir/ {
internal;
root /home/username/public_html/wordpress/wp-content;
}

Adding APC Support for a Virtual Domain

Because Virtualmin’s implementation of Nginx uses php-fastcgi, each virtual domain will load its own php.ini file, so you can add the APC directives to that file (/home/domainname/etc/php5/php.ini)

Add the following to php.ini (adjust to your requirements)

[APC]
extension = apc.so
apc.enabled = 1
apc.shm_segments = 1
apc.shm_size = 12M
apc.optimization = 0
apc.num_files_hint = 256
apc.user_entries_hint = 1024
apc.ttl = 0
apc.user_ttl = 0
apc.gc_ttl = 600
apc.cache_by_default = 0
apc.filters = "-/home/username/public_html/scripts-not-to-cache/.*,-/home/username/public_html/apc/.*"
apc.slam_defense = 0
apc.use_request_time = 1
apc.mmap_file_mask = /tmp/apc.XXXXXX
apc.file_update_protection = 2
apc.enable_cli = 0
apc.max_file_size = 2M
apc.stat = 1
apc.write_lock = 1
apc.report_autofilter = 0
apc.include_once_override = 0
apc.rfc1867 = 0
apc.rfc1867_prefix = "upload_"
apc.rfc1867_name = "APC_UPLOAD_PROGRESS"
apc.rfc1867_freq = 0
apc.localcache = 1
apc.localcache.size = 256
apc.coredump_unmap = 0
apc.stat_ctime = 0

Reloading PHP-fastcgi processes after changes to php.ini

You will need to reload the php-fastcgi processes if you change php.ini. Luckily, Virtualmin creates service scripts for each virtual domain, which you can use to reload PHP.

The service scripts are located in /etc/rc.d/init.d.
php-fcgi-domain1-com
php-fcgi-domain2-com

Script allows stop, start, restart
e.g.
service php-fcgi-domain2-com restart

The service may also be restarted via Webmin > Services > Bootup and Shutdown

Memory Considerations

PHP FCGId will launch the number of sub-processes you specify in Virtualmin > Server Configuration > Website Options, so beware of the memory overhead if you specify a large number, because each will consume the amount of memory specified in  apc.shm_size. You may need to experiment with this value, depending on your server’s memory and potential traffic.

Virtualmin explains: “When PHP scripts for this domain as run via FCGId, the number of PHP processes set in this field will be kept running at all times to serve requests. You can increase this from the default of 4 to improve PHP script latency, or decrease it to reduce memory use. Setting it to None will cause PHP processes to be launched only as needed on demand, and to be cleaned up after some period of inactivity.”

Nginx support on Virtualmin is working well, and it is reported that the lead developer, Jamie Cameron, is working on a php-fpm implementation, which should increase performance and lessen memory requirements. Let’s hope this rumor is true!

W3 Total Cache Settings

Provided you use the nginx.conf settings described above, using APC cache for all W3TC categories of cache/minify/etc. will work with no additional changes to the conf file. However, if you wish to choose Disk cache for page and/or minify cache, URL rewriting will not work properly on Virtualmin. You must include the location {…} directives in the nginx.conf created in your public_html root by W3TC, and add them after the location {…} directives described above.

You can do this either by copying the directives and pasting into /etc/nginx/nginx.conf, or (better) by using an include statement:

[...]
location ^~ /blogs.dir/ {
internal;
root /home/username/public_html/wordpress/wp-content;
}
include /home/username/public_html/nginx.conf;
[...]

However, remember you will need to restart NginX web server after making changes to the W3TC configuration, because these will over-write the local nginx.conf file.

Conclusion

Sorry, no benchmarks. See my example/test site here.

Nginx support on Virtualmin is working well, though I don’t see much improvement over Apache in terms of initial index page load, or time to first byte on the WordPress test site I created.  Cached and subsequent pages load very quickly, so it looks like there is an overall improvement. All WordPress functions seem to work well: comments, image uploads, etc. are no problem. I am interested to see if there is improvement with other scripts, especially phpbb3.

The post WordPress with W3 Total Cache on Nginx with APC (Virtualmin) appeared first on Chris Gilligan » new media.

]]>
https://chrisgilligan.com/wordpress/wordpress-with-w3-total-cache-on-nginx-with-apc-virtualmin/feed/ 20