Viewing technology View all News

New Work: Bright Bright Great and Pentagram for Arkana Laboratories

Introducing Arkana Laboratories, a center for esoteric pathology focused on one thing:
improving care for patients.

Bright Bright Great has been working with Arkansas-based Nephropath since 2012 and are excited to announce our continued relationship with them as they not only expand their services and offerings, but reinvent their brand as Arkana Laboratories.

For the relaunch NYC-based Pentagram, handled the Brand Identity Refresh and Digital Art Direction. Bright Bright Great handled digital UX, Front-End Development and Third Party Integrations/Technology.

Arkana Index BBG Pentagram

Arkana Internal Page BBG Pentagram

Arkana Mobile Site BBG Pentagram

Posted By
Jason Schwartz

WordPress Static Page Cache

WordPress is a dynamic application. When a page is requested, the application loads hundreds or thousands of files into memory, makes dozens or hundreds of database queries, and eventually, crafts a static HTML document, which the visitor’s web browser can then render as a web page.

All of this happens every time someone pulls up a web page.

As you might imagine, the complexity of such operations can put quite a strain on humble web servers. As traffic levels increase, the struggle to meet the demands can result in WordPress sites slowing to a crawl or worse, crashing.

Investments in better hardware will postpone the inevitable, but to really address the problem head on, one must eliminate the dynamic nature of WordPress.

By saving a static copy of the page being generated to the server, the chain of events must only occur once; after that, the server need only hand over the ready-made page when visitors request it.

This is the perfect solution for content-driven web sites like blogs and portfolios. When changes are made to the database (e.g. a new post is published, or an old one is edited), the author can simply clear the cache and the site is good as new!

This solution is not so good for interactive user sites like stores and forums, where access to realtime data or personalized templates are required. At the end of this article, we’ll examine some tricks that might still offer assistance for these types of sites.

W3 Total Cache

There are a lot of caching plugins available to WordPress, but none are as comprehensive as W3TC. It is available in both free and premium versions, however for users looking at just the static page caching functionality, the free version will suffice.

First things first, install it.

Once activated, you’ll find a “Performance” tab in the admin menu. Go to “Performance” > “General Settings” to enable page cache (to disk). Now go to “Performance” > “Page Cache” to configure settings specific to page caching. For most sites, the default settings will suffice. If you have any pages that need to be served dynamically, such as a contact form or a page displaying randomized content, you can add it to the list of “Never cache the following pages”.

That’s it!

You can verify page cache is working by looking at the source code of a page on your site. You should see something like the following at the end:

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/
Page Caching using disk: enhanced
Served from: brightbrightgreat.com @ 2015-07-11 10:17:07 by W3 Total Cache -->

If page cache is disabled for logged in users, you might instead see:


<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/
Page Caching using disk: enhanced (User is logged in)
Served from: brightbrightgreat.com @ 2015-07-11 11:14:21 by W3 Total Cache -->

The (User is logged in) lets you know that page cache would be used, were it not for the fact that logged in users are specifically excluded from it.

W3TC has a lot of features beyond page cache that are worth checking out. “Minify” will attempt to compress static documents before saving them to disk, which can result in faster load times for users.

Minification can break things in unexpected ways, so if you enable it, carefully double-check that your site is still working as expected (you can use an Incognito/Private session to view the site as a regular visitor would see it without having to log out of your account). If your server is already gzipping requests, you probably won’t see substantial performance gains from Minify.

To completely clear your static page cache, click “Performance” > “Empty All Caches” in the admin toolbar. If you forget to do this, the cache will empty itself automatically eventually.

Advanced

The biggest disadvantage to using static page cache is that pages are, well, cached. If a web site allows users to log in and then shows them personalized content (e.g. “Welcome back, Jane!”), static page cache won’t work correctly; all visitors will receive the same static page. Either Jane won’t see her message, or everyone will see Jane’s message.

One possible workaround is to disable cache for logged in users, but allow it for everyone else. If your site users are simply low-privilege WordPress users (e.g. subscribers), this is the default behavior anyway. But cache can also be disabled by the presence of a cookie; if user sessions are controlled through custom code, set a cookie at login (and remove it at logout), and add the cookie name to “Rejected cookies” list.

For sites where the session-specific variation is minimal, it might be preferable to maintain static page cache for all users, and let Javascript make any necessary adjustments at runtime.

A good example of this would be a storefront that displays the current cart count in the toolbar. As items are added to the cart, the count could be written to a cookie, which Javascript could then read and plop into place. Highly specific pages like the shopping cart could be individually excluded from cache, ensuring they are always up-to-date.

Lastly, it might be necessary for sites to clear the page cache programmatically. For example, if a product page lists its availability, that figure should be adjusted when a new order is placed.

To do this, make a wrapper function like the following (add/remove caches as necessary), and include calls to it where needed:

function my_cache_clear(){
	//clear W3TC page cache
	if(function_exists('w3tc_pgcache_flush'))
		w3tc_pgcache_flush();

	//clear W3TC database cache (comment out if not using)
	if(function_exists('w3tc_dbcache_flush'))
		w3tc_dbcache_flush();

	//clear W3TC object cache
	if(function_exists('w3tc_objectcache_flush'))
		w3tc_objectcache_flush();

	//clear W3TC minify cache
	if(function_exists('w3tc_minify_flush'))
		w3tc_minify_flush();
}

These techniques are no substitute for good coding and asset optimization, but they can give your site a boost and help make sure pages load quickly and efficiently.

Posted By
Josh Stoik

After All These Years We’ve Finally Solved It! Cracking the Code: Search Engine Optimization (SEO)

seo-bundle

In our strategy and marketing work, it is not uncommon for us to have in-depth conversations with our clients on the subject of Search Engine Optimization (SEO). In the heyday of the tech boom, SEO was everywhere, as companies took their competition online and fought to go to the top of search rankings by whatever means were at their disposal.

Early on, this meant essentially paying for advertising. Once Google broke through, with their purely algorithm-driven results,  as the search engine of choice for most users, this changed to making sure that companies were establishing a digital record of their prominence within their fields.

Some less scrupulous competitors turned to the dark arts, paying companies to load their pages and code with unusable links to irrelevant websites to trick search engines into thinking that more people were linking to their site than was actually the case. Eventually, this came full circle, with the only way to insert yourself into an otherwise algorithmically-determined search order being paying for placement.

Clients have been asking us for years how to trick people into buying their product on the internet and we haven’t had a concrete answer on how to do it. Today we think we finally got this right.

Jason Schwartz, SEO Specialist

Until today. Today, April 1st, Bright Bright Great is proud to announce that we have cracked Search Engine Optimization once and for all: by helpfully pointing out where search engines can find SEO,  namely in all of our links.

You will notice on our site that we have politely and helpfully appended the phrase “SEO” to all of the links on our site, in order to make it as plain as possible that these portions of our site are there to highlight our areas of expertise and that interested users should click those links in order to find relevant information.

With this new strategy, it has never been simpler to ensure that you are getting the maximum result for your content marketing efforts: by politely asking for more SEO by noting to search engines where they can find your optimized content on your site.

I mean, SEO is pretty much the best trick around.

Nick Lush, SEO Marketing, Strategy, Link-Building, Content Stuffing, White Hat Marketing Specialist

Posted By
Nick Lush

How to Log MySQL Errors in WordPress

MySQL query errors can be difficult to diagnose and correct.

For performance reasons, most MySQL installations fail to retain an error log for posterity; instead, if an error occurs, the reason is passed back to the application during runtime. If that error isn’t captured then and there, it is lost forever.

Development Environments

WordPress contains a special development mode that can be enabled by adding WP_DEBUG, WP_DEBUG_LOG, and/or WP_DEBUG_DISPLAY constants to your configuration. When enabled, PHP errors/warnings/notices and MySQL errors will be logged to wp-content/debug.log and/or printed to the screen.

WordPress’s $wpdb object also provides some debugging functions in case you wanted to debug MySQL issues independently of PHP ones:

  1. $wpdb->show_errors(): this causes MySQL error information to be printed to the screen as it happens. You would call this function before the queries you are looking to debug.
  2. $wpdb->hide_errors(): this reverses the behavior of show_errors() and returns WordPress to its default configuration. You can call this function anytime after executing the questionable queries.
  3. $wpdb->print_error(): this prints the error, if any, from the most recent query.

Production Environments

These tools are probably all you need when developing a new theme or plugin, but you shouldn’t use these under production environments. For one thing, printing random, technical-looking strings in the middle of a document will break the layout and confuse your users. It can also provide interesting information to any bad actors who might be poking around your site. But even if you’re just logging the information, WP_DEBUG_LOG isn’t a great idea: it degrades your site performance and, under most server configurations, exposes way too much information to anyone who knows where to look.

Of course, by the time a site is live, you should have thoroughly debugged everything, so there’s no need to log query failures, right? Well… maybe.

There are a lot of ways to mess up a MySQL query. Chances are, no matter how many times you tested your code during development, you’ll have missed some highly obscure edge case. Even if you didn’t, and everything was coded perfectly, sometimes an update to the WordPress core can subtly change the way a query is structured.

Such a change occurred recently with the release of WordPress 4.4. In prior versions, Null values passed via $wpdb->insert() or the like were typecast according to the type specified. %s would convert a Null value to '', %d to 0, etc. Now, however, Null values are passed as-is to MySQL. For columns with NOT NULL attributes, this can create problems where previously none existed.

So what to do?

Though we were unable to find any documentation, investigation into the WordPress source code revealed that MySQL errors from the current page request are collected in an obscure global variable during runtime, $EZSQL_ERROR.

We can access this variable in a custom PHP function that we then trigger through one of WordPress’ action hooks. Since we want to capture all errors for a given page request, the shutdown action is the best candidate as it triggers just before PHP terminates.

The following example code block does just that. At the end of every WordPress page execution, the function looks to see if any MySQL errors were encountered. If there were any, it combines some basic runtime information (date, page, etc.) with the error details and emails it to the site administrator.

//-------------------------------------------------
// Database logging - query errors
//
// email database query errors to the contact
// specified
//
// @param n/a
// @return n/a

function db_debug_log(){

	//WP already stores query errors in this obscure
	//global variable, so we can see what we've ended
	//up with just before shutdown
	global $EZSQL_ERROR;

	try {
		//proceed if there were MySQL errors during runtime
		if(is_array($EZSQL_ERROR) && count($EZSQL_ERROR)) {
			//build a log entry
			$xout = array();

			//let's start with some environmental information
			$xout[] = "DATE: " . current_time('r');
			$xout[] = "SITE: " . site_url();
			$xout[] = "IP: " . $_SERVER['REMOTE_ADDR'];
			$xout[] = "UA: " . $_SERVER['HTTP_USER_AGENT'];
			$xout[] = "SCRIPT: " . $_SERVER['SCRIPT_NAME'];
			$xout[] = "REQUEST: " . $_SERVER['REQUEST_URI'];
			$xout[] = "\n\n\n\n";

			//and lastly, add the error messages with some line separations for readability
			foreach($EZSQL_ERROR AS $e) {
				$xout[] = str_repeat('-', 50) . "\n" . implode("\n", $e) . "\n" . str_repeat('-', 50);
				$xout[] = "\n\n\n\n";
			}

			//email it!
			//if a plugin overrides the content-type header for outbound emails, change the message body
			//below to nl2br(esc_html(implode("\n", $xout)))
			wp_mail(get_bloginfo('admin_email'), '[' . get_bloginfo('name') . '] DB Error', implode(“\n”, $xout));
		}
	} catch(Exception $e){ }

	return;
}
add_action('shutdown', 'db_debug_log');

If email isn’t desirable, whether for reasons of security or practicality, the general idea could be altered to push data via error_log() or write the contents to any arbitrary log file (preferably in a non-web-accessible location).

These techniques can help make hunting down elusive MySQL errors easier. With a proper record in place, developers can see what went wrong and where, and find a solution more quickly.

Posted By
Josh Stoik

Recommended WordPress Plugins

We’ve worked on hundreds of WordPress sites, and with that we’ve had experience with a great number of WP plugins, as well as written our own.

Over the years we’ve come to trust certain plugins and we end up using them on almost every installation.  This is a list of our go-to plugins that we can wholeheartedly recommend to others:

Security

Apocalypse Meow
Written by our own security expert, Josh Stoik, this plugin is a powerhouse. It has brute-force login protection, minimum password requirements, a history of log-in attempts, email notifications for logins from new locations, and a slew of other security-minded features. It’s the first plugin we install when we set up WordPress.

Look-See Security Scanner
Another plugin by the inestimable Josh Stoik. This plugin acts as a scanner over your WordPress installation to try and detect any malicious or unexpected code. It also analyzes your site and alerts you to measures you can take to batten down your WP installation even further.

Sock’Em SPAMbots
Yet another from Josh Stoik, this plugin gives you a variety of options for blocking SPAM comments, such as honeypots, speed tests, maximum number of links in a comment, and more. SPAMbots plays well with Akismet for even more SPAM fighting power.

Optimization

W3 Total Cache
This plugin is a must-have for a blazing fast WP site. It has both object, page, and data cache, as well as options for minification and CDNs.

Media

Post Thumbnail Editor
Sometimes the automatically cropped images that WordPress generates are just not quite right. This plugin let’s you manually recrop any image for any particular image size. A godsend for anyone with a particular sense of art direction.

Force Regenerate Thumbnails
If you’re working on an existing installation and add new image sizes, WordPress doesn’t automatically go back through old images to crop them accordingly. This plugin forces all image sizes to be regenerated, so you can be sure all your images, old and new, are properly cropped.

It also deletes image sizes that no longer exist, clearing up some space on your server. One thing to note is that it will blow away any manual crops made with Post Thumbnail Editor. For that reason, we don’t recommend running Force Regenerate Thumbnails on a production environment, only during the development phase when specific art direction crops aren’t likely to have been set up yet.

Content Management

Advanced Custom Fields Pro
THE WordPress plugin that makes leveraging WordPress as a robust and flexible CMS easy as pie. Add custom fields to posts, pages, taxonomy, attachments, almost anything you can imagine. Add that to the variety of field types, as well as all conditional rules you can establish and you have an indispensable plugin. More than anything else, ACF Pro is our desert island plugin.

Simple Page Re-Ordering
If you’re using menu_order to order any of your post types, this plugin allows you to re-order those posts by simply dragging and dropping the posts in the desired order. Super simple and incredibly useful.

Admin Area

Admin Menu Editor
Admin Menu Editor gives you tools to customize the admin dashboard menu. You can add custom links, or hide existing ones. We find it useful for hiding development-related menu items from clients and cleaning up the menus of unecessary clutter.

Admin Columns
This plugin lets you customize columns to post listings in the backend. You can hide existing columns or add new ones, with options like featured image, word count, custom fields, and more. It also has an ACF Pro add on so you can easily map ACF fields to the columns.

Admin Collapse Subpages
If you have a lot of subpages, this plugin is a must. As the name might imply, it provides the ability to collapse subpages so only top-level pages are immediately visible. It makes it much easier to navigate a subpage-heavy backend.

Misc

Search Everything
Improves the WordPress search by allowing you to customize exactly where a search looks for matches. You can add search support for custom fields, custom taxonomies, attachments, and more.

While we use other plugins as necessary, we try to keep plugin use to a minimum on any given project to avoid conflicts and instability. The plugins listed here always make the cut because of how useful and reliable they are.

Posted By
Tiffany Stoik