Dev4Press» WordPress Archives, page 1 of 1 – Dev4Press http://www.dev4press.com Premium Plugins and Themes for WordPress Thu, 16 May 2013 18:33:45 +0000 en-US hourly 1 My site is stuck in Maintenance mode, what now? http://www.dev4press.com/2012/tutorials/wordpress/tips/my-site-is-stuck-in-maintenance-mode-what-now/ http://www.dev4press.com/2012/tutorials/wordpress/tips/my-site-is-stuck-in-maintenance-mode-what-now/#comments Wed, 26 Sep 2012 16:00:59 +0000 MillaN http://www.dev4press.com/?p=18220 When WordPress upgrades plugins and themes, it will enable maintenance mode to prevent website modifications during the update. But, in some cases, this maintenance mode will not get disabled after the upgrade, and your website will be unaccessible. What can you do?

WP activates maintenance mode when upgrading active plugin, or when in network/multisite environment. In same very rare cases, this mode doesn’t get disabled after the upgrade. But, you can disable it using FTP. Simply, open FTP and connect to your website, in the website root directory where wp-config.php, wp-load.php, wp-login.php and wp-admin are, you will see file called: ’.maintenance‘. Yes it starts with the dot, just like .htaccess does. Simply delete that ‘.maintenance‘  file and your website will start working again.

If you don’t have FTP access to your website, you can use access through your hosting control panel or you need to contact your hosting company and get their support people to remove that file for you.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/tips/my-site-is-stuck-in-maintenance-mode-what-now/feed/ 0
URL Rewriting: Custom Post Types Date Archive http://www.dev4press.com/2012/tutorials/wordpress/practical/url-rewriting-custom-post-types-date-archive/ http://www.dev4press.com/2012/tutorials/wordpress/practical/url-rewriting-custom-post-types-date-archive/#comments Wed, 18 Apr 2012 11:05:41 +0000 MillaN http://www.dev4press.com/?p=15392 Last month I have published and article about WordPress rewriting as an intro to give better understanding what is happening behind the scenes when WordPress needs to resolve URL. This time, I will give you practical example to add date based archives to custom post types.

Before we go on, here is the previous article on rewriting:
How WordPress URL rewriting works?

Date based archives by default, work only with the default posts post types, and they look like this:

Year archive: http://www.example.com/2011/
Month archive: http://www.example.com/2010/10/
Day archive: http://www.example.com/2012/02/22/
Month archive, feed: http://www.example.com/2010/10/feed/
Year archive, page 2: http://www.example.com/2012/page/2/

But, to get similar URL’s for the custom post types, will not work. Also, each of theses URL’s supports pages and feeds as you can see on the last two examples.

If we have post type names ‘movie’, and for the post type archive slug we have set ‘movies’, you expect to get these date based archives for it:

Year archive: http://www.example.com/movies/2011/
Month archive: http://www.example.com/movies/2010/10/
Day archive, feed: http://www.example.com/movies/2012/02/22/feed/
Year archive, page 5: http://www.example.com/movies/2011/page/5/

Such URL’s will filter posts by post type and date, returning date based archives for a post type. But, it is not that hard to do this. What’s more, there are two ways you can do it: using a plugin and doing it your self with custom coding.

Using GD Custom Posts and Taxonomies Tools Pro

If you prefer to do things from the comfort of the admin interface, and if you need to do this for many post types, my GD CPT Tools Pro plugin is a best solution. You can add and manage any number of custom post types and you get long list of extra features plugin implements, including custom rewriting that includes date based archives.

GD CPTTools Pro: Enable Date Based Archives

GD CPTTools Pro: Enable Date Based Archives

For each custom post type, plugin includes many more rewrite options. On the rewrite tab, you can set up permalink structure for single posts, and you can control archives for post type. Simply enable the Date based archives checkbox (like on the image on the right), save post type, and plugin will generate rules for these archives.

If you want to check the rest of this plugin features, you can do it from here:

GD CPT Tools Pro Own Website: www.gdcpttools.com
GD CPT Tools Pro On Dev4Press: www.dev4press.com/gd-taxonomies-tools

Do it yourself with example code

If you prefer to do this yourself, here is the code that GD CPT Tools Pro uses for the date based archives. For the year, month and date archives you need one extra rewrite rule. And, if you want to have feeds and pages for them, you need 3 more rules for each one. So, in total there are 12 new rules for each post type for the date based archives. For this to work, we need to hook into action ‘ generate_rewrite_rules ‘:

add_action('generate_rewrite_rules', 'my_datearchives_rewrite_rules');

function my_datearchives_rewrite_rules($wp_rewrite) {
  $rules = my_generate_date_archives('movie', $wp_rewrite);
  $wp_rewrite->rules = $rules + $wp_rewrite->rules;
  return $wp_rewrite;
}

This code attached  ‘my_datearchives_rewrite_rules’ function to ‘generate_rewrite_rules’ action. On line 3, we call another function that will generate rules for a post type ‘movie’. We than add those rules to existing WP rules, and return rewrite object. Now we need the function that generates rules for specified post type.

function my_generate_date_archives($cpt, $wp_rewrite) {
  $rules = array();

  $post_type = get_post_type_object($cpt);
  $slug_archive = $post_type->has_archive;
  if ($slug_archive === false) return $rules;
  if ($slug_archive === true) {
    $slug_archive = $post_type->name;
  }

  $dates = array(
            array(
              'rule' => "([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})",
              'vars' => array('year', 'monthnum', 'day')),
            array(
              'rule' => "([0-9]{4})/([0-9]{1,2})",
              'vars' => array('year', 'monthnum')),
            array(
              'rule' => "([0-9]{4})",
              'vars' => array('year'))
        );

  foreach ($dates as $data) {
    $query = 'index.php?post_type='.$cpt;
    $rule = $slug_archive.'/'.$data['rule'];

    $i = 1;
    foreach ($data['vars'] as $var) {
      $query.= '&'.$var.'='.$wp_rewrite->preg_index($i);
      $i++;
    }

    $rules[$rule."/?$"] = $query;
    $rules[$rule."/feed/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
    $rules[$rule."/(feed|rdf|rss|rss2|atom)/?$"] = $query."&feed=".$wp_rewrite->preg_index($i);
    $rules[$rule."/page/([0-9]{1,})/?$"] = $query."&paged=".$wp_rewrite->preg_index($i);
  }

  return $rules;
}

To fully understand this code, you need to understand PHP regular expressions, but if you just want to use it, no worries, it is all here and this function doesn’t need to change. Let’s see what is going on in this function. Function is called with two arguments: name of the post type ($cpt) and the WP rewrite object ($wp_rewrite).

First, we need to find out what is the slug for the archives URL for this post type ($slug_archive). If you have disabled archives for post type, this function will exit on line 6. If the archives are set to use custom slug, function will use that, or it will use post type name (lines 7-9). Lines 11 to 21 are used to set up day, month and year based regular expressions rules and variables to be used in the query. First one is for day and it needs year, month and day, month based needs year and month, and year based only year. After that, we go through these 3 archives types and we generate rules for them. In the rule part we use regular expressions, and it uses ( and ) to separate capture groups. Each capture group provides a value for us to use, and each of these values need query variable in the query part of the rewrite rule.

Line 24 sets up the base for the query using post type name and on 25 we set up base for the rewrite rule using post type archives slug and the rule for the archive. Now, we need to add to the query all the variables needed for the rule (27 to 31). This builds the basic rewrite rule and rewrite query rule point to. Lines 33 to 36 are setting up rules for basic archive rule, feeds and pages. Feeds and pages need extra bits for the regular expression to detect feed or page, and extra query variable for feed or page. If you don’t want to have feeds for these date based archives, you can remove lines 34 and 35. Line 33 adds basic rewrite rule, and line 36 adds pages for archives, and you need to leave these two in place. After all the rules are generated, they are returned back to the rules in ‘ my_datearchives_rewrite_rules’ function, merged with WP rules and ready to use.

Whenever you make changes to rewrite rules, you need to instruct WordPress to rebuild the cached rules. To do this, it is enough to open Permalinks panel on the WordPress admin side under Settings. If you use GD CPT Tools Pro and its rewrite features, this plugin will flush rules on its own when needed.

Conclusion

Adding extra rewrite rules is not that complicated as you can see from this practical example. Depending on what you need, you need to learn (at least basics) PHP regular expressions and to make sure that query for the rule has sufficient number of variables to correspond to the number of capture groups in the regular expression. If you don’t want to lose time over this, and you need these extra rules, get yourself GD Custom Posts And Taxonomies Tools Pro and add new features with just a few clicks.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/url-rewriting-custom-post-types-date-archive/feed/ 5
Expand WP Query: Taxonomies Terms http://www.dev4press.com/2012/tutorials/wordpress/practical/expand-wp-query-taxonomies-terms/ http://www.dev4press.com/2012/tutorials/wordpress/practical/expand-wp-query-taxonomies-terms/#comments Tue, 03 Apr 2012 20:00:25 +0000 MillaN http://www.dev4press.com/?p=15602 WordPress Query object is very powerful, and it allows you to filter posts with all sorts of criteria. One of the most important filters are taxonomy terms. You can filter using one or more taxonomies and one or more terms for each taxonomy. This tutorial will show you how.

Taxonomies terms filtering can be done only for taxonomies that are registered as public, and have set query variable. Query variable is the same as taxonomy name by default, but it can be registered to be anything as long as it is clean and URL safe (query variables are used in URL, so they can’t contain empty spaces or special characters). For instance, default WP taxonomies – category and post tags have query variables - category_name and tag.

URL Query

Taxonomies query variables can be used in URL like this:

// archive for category with name 'news' //

http://www.example.com/?category_name=news

// archive for category with name 'news' and post tag with name 'latest' //

http://www.example.com/?category_name=news&tag=latest

You can use more taxonomies in the URL like this, and you can even specify multiple terms separated by comma. But, the more terms you try to filter, number of posts will be smaller, and if you specify filter that gives no results, you will be redirected to 404 page (or to empty archive with no posts message).

Override the WP Query

It is useful to be able to override already prepared query and add filters for terms. This way you can modify query for archives by adding additional conditions. To do this, you need to use ‘pre_get_posts’ action, and to modify query arguments with function attached to that hook. Here is the example.

add_action('pre_get_posts', 'example_pre_get_posts_simple'));
function example_pre_get_posts_simple($query) {
  $query->set('tag', 'latest,wordpress,video');
  $query->set('category_name', 'news');
}

This example will expand query with filters for 3 terms belonging to post tags (comma separated strings: latest, wordpress and video) and one term belonging to category. Based on this Query class will generate tax_query object that contains elements that will be used to filter posts by taxonomies you have set and taxonomies that were already in the Query object before you hooked into it with pre_get_posts action. You can even modify tax_query with this hook, but that is not recommended because parsing taxonomies will be done once again after pre_get_posts. Still, it can be done, but you need to make sure you preserve old tax_query variable before adding your own. Tax_query elements are much more complicated than the example above, and you can specify relations for the terms and you can specify terms with ID’s or name, not only slug. Third method bellow shows how to get posts using custom tax_query array.

Using get_posts function

This function has many different ways to filter using terms. Function get_posts has an array of arguments, and there is a long list of parameters you can use with it, so you can specify posts count, post type, tags, categories, post ID’s and much more. First few examples are simple ways to specify terms:

//use category ID:
$posts = get_posts(array('category' => 1));

//use category slug with category query variable:
$posts = get_posts(array('category_name' => 'news'));

//use category slug and post tags slugs for 3 terms:
$posts = get_posts(array('category_name' => 'news', 'tag' => 'latest,wordpress,video'));

You can add more things here including custom taxonomies, using query variables for those custom taxonomies. Full list of parameters you can use can be found here: WP Query Parameters.

Another thing you can do is to specify terms using tax_query array. This allows more flexibility in specifying terms. Tax query is actually array of arrays. Each array is to specify the taxonomy terms and it is in form of array that has few parameters of its own. Each tax_query array can have 5 parameters:

  • taxonomy: name of the taxonomy, actual name, not query variable
  • field: it can be slug or ID, and it is used to define what is used to specify terms
  • terms: single ID or slug, or array with slugs or ID’s based on field parameter
  • include_children: should the children of terms be included, only for hierarchical taxonomies, and by default is set to true
  • operator: what operator to use in SQL query to link the specified terms: ‘IN’, ‘NOT IN’, ‘AND’

So, here is the example with two taxonomies:

$args = array(
  'tax_query' => array(
    array(
      'taxonomy' => 'post_tag',
      'field' => 'slug',
      'terms' => 'latest,wordpress,video'
    ),
    array(
     'taxonomy' => 'category',
     'field' => 'id',
     'terms' => 1
    )
  )
);
$posts = get_posts($args);

This will filter posts using 3 terms for post tags, specified by slugs, and by one category specified by ID.

There are a lot of possibilities to filter posts by multiple taxonomies and multiple terms. You need to choose method which works best for you, depending on what you need to do and how to filter posts, and be careful with listing multiple terms: more terms in the filter, the less posts you will get, or you will get no posts due to number of filter rules, and you can get to 404 page with no results.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/expand-wp-query-taxonomies-terms/feed/ 3
How WordPress URL rewriting works? http://www.dev4press.com/2012/tutorials/wordpress/practical/how-wordpress-url-rewriting-works/ http://www.dev4press.com/2012/tutorials/wordpress/practical/how-wordpress-url-rewriting-works/#comments Wed, 14 Mar 2012 13:00:12 +0000 MillaN http://www.dev4press.com/?p=15288 On of the most important features WordPress has is permalinks rewrite engine that can create all those pretty links we are so used to with no query elements like question marks or ampersand. Did you wonder how permalinks work and what can you do to customize them? Read on.

This article explains what happens when WordPress resolves URL request that uses pretty permalinks. This article doesn’t include examples with creating custom permalinks structures. I am planning to have additional articles to cover that.

By default, pretty permalinks are disabled in WordPress. Reason for that is that in some cases they can’t be activated without user intervention. For pretty permalinks to work, WordPress needs access to .htaccess file (if on Apache server) where it needs to add few lines that are base for the rewrite engine in WordPress. And that also requires Apache mod_rewrite module. This module is part of Apache installations and it is very rare that it is missing. Code added into htaccess file basically redirects all URL’s to WordPress index.php and that allows WordPress to break URL into parts and using regular expressions detect what content to display.

WordPress supports also PATHINFO permalinks that don’t require mod_rewrite module, but permalinks in that case must start with index.php. More info on this you can find on the WordPress Codex Permalinks page (links are at the end of this article). There are some setup differences in using permalinks for Apache, IIS or other servers, but they can work with any of the currently available servers for Windows, Linux or MacOS.

So, basic thing to activate rewrite engine in WordPress is to enable permalinks from WordPress Settings/Permalinks panel. If it is set to Default, permalinks are disabled, any other value they are active.

Why do you need these permalinks?

Well, there are many reasons, and most important reasons are SEO and that they look much nicer and user-friendly than long query strings in URL. Especially if you have complex website structure. Search Engine Optimizations benefits from permalinks, because they contain more relevant information about the content, and most search engines have a use for that when indexing websites.

Older versions of WordPress were known to work slower because of some permalinks structures that required additional SQL queries, but since WordPress 3.3 most critical permalinks structures are optimized and there is no performance penalty if you use post name only in the URL. Even with older WordPress versions performance was affected with only some structures and with large number of posts.

Permalinks are a must in a website, and very few WordPress websites don’t use it (mostly default installations, left with permalinks disabled). What to choose for permalinks is another matter.

Default permalinks settings

To quick start using the permalinks, you can select one of the predefined rules from Permalinks panel. Also, you can see Custom Structure field where you can create structure you want. What this panel doesn’t say is that those rules are only for posts (default post type: post). WordPress allows you to customize only this post type rewrite rules, nothing else! Pages in WordPress always use same rewrite structure: only sanitized version of the page name. And, that is the rule you can’t change. For archives, Permalinks panel offers only two settings: what to use as a base for category and tags archives.

Beside this, there are plenty more rewrite rules that WordPress will not allow you to change (well, not directly anyway). These rules include: archives for authors, date base archives, attachments, feeds, custom post types, custom taxonomies and generic archives.

When you create rules on the Permalinks panel, you don’t need to handle regular expressions, but you can use special tags to form the URL. By default, WordPress uses several structure tags (full list in the Codex, check the link at the bottom). If you use these tags in the URL they will be replaced with actual data. If element in the URL is not recognized, it will be left like that as a part of URL. This way you can add static parts of the URL.

Most things in WordPress use more than one rewrite rule. To resolve year based archive, WP needs separate rules to match: basic year archive URL, URL with page numbers and feed URL. Some things need more than 3 rules, for a post you need 5 rules.

Resolving rewrite rules

To resolve URL, WordPress uses a list of rewrite rules. Rules are based on regular expressions, and each regular expression in the list points to a query based URL. For instance, here is the rule to resolve author archive feed:

Regular Expression: author/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$
WP Resolved Query: index.php?author_name=$matches[1]&feed=$matches[2]

I am not going to go into how regular expressions work, but URL is matched against all regular expressions in the rules list, until we get a match. When URL is matched against expression, query for that expression is than used to resolve requested URL to a query based URL. In the query in example above you see $matches[1] and $matches[2]. These are values detected by regular expression from requested URL. These values are URL parts marked with ‘(‘ and ‘)’ in the regular expression. So, if your URL is this:

http://www.example.com/author/admin/feed/rss/

Website URL part is removed, and we get the request:

author/admin/feed/rss/

This is what WordPress than matches against the rewrite rules, it will match it against our example expression above. Words ‘admin’ and ‘rss’ are matched/extracted from regular expression, they are replacing $matches[1] and $matches[2] and resolved query based URL is now this:

index.php?author_name=admin&feed=rss

And this is something WordPress can use to prepare page, load template and data for it. This final query is used to create WP Query object that is ultimately used to get posts for that request.

If all rewrite rules fail, the last rule will always resolve. This base rule resolves any request to a page request. If that page is not found, you get 404 error. If the URL is resolved by some rewrite rule, and the WordPress Query doesn’t find any results to match, again you will get 404 error.

Custom rewrite rules

If you need to customize URL for posts, you can use Settings Permalinks panel and do it from there. But, anything else you must do it through code. WordPress 3.0 added support for custom post types, and there is one very important thing missing: custom rewrite rules for them. All custom post types by default have same URL structure that includes name for the post type and name for the post. Same thing goes for the archives for the post types, or date base archives. Nothing can be customized without custom coding.

But, there is even more important use for custom permalinks. Each URL is resolved to a query that WordPress uses to get posts. So, date based query and URL filter posts by the date. If you request this:

http://www.example.com/2012/03/

You will get all posts published in the year 2012, in March. And if you want to get all posts belonging to custom post type movie, you can use this:

http://www.example.com/movie/

But, what to do if you want to get all posts for custom post type movie for 2012? You would like it to be this:

http://www.example.com/movie/2012/03/

But, there is no rule for that in WordPress and this will not work, so instead this elegant link you must use only this:

http://www.example.com/movie/?year=2012&monthnum=3

Anything that is part of the URL: resolved by WordPress or added like here with direct query element is used in WordPress Query engine to get posts. There are many examples where additional rewrite rules can make a big difference in getting cleaner links.

Most important thing is filtering posts by post type and taxonomy. Normally, you have URL that filters posts by post type or by taxonomy term. If you want to mix those, you need to use query elements. So, if your movie custom post type has taxonomies category and genre, to filter by both with URL you need to use something like this:

http://www.example.com/movie/?cat=short&genre=animated

But, what if you can do it like this:

http://www.example.com/movie/short/animated/

That would be great, and if you have more taxonomies you can have more terms listed like this, one term for each taxonomy. But, again, this can’t be done without using custom coding to implement additional rewrite rules and you can’t use such links…

GD Custom Posts and Taxonomies Tools Pro

…Oh wait, you can!

Ever since custom post types are added to WordPress, I used them for many things, and I always hated limitations with permalinks. So, I started adding customized rewrite rules with my GD Custom Posts and Taxonomies Tools Pro plugin. Plugin now allows fully customized single post permalinks for custom post types (just like for default posts), date based archives for custom post types and archives with intersection of custom post types and taxonomies. All that without any additional coding, just by setting rules for each custom post type you add through this plugin.

Check out this tutorial with examples to see what can be done with this plugin and custom post types. All this is used on Dev4Press for Central Documentation and Feature of Day sections to filter posts by terms. I have few more ideas for additional rewrite rules and more customizable links structure.

Canonical Redirect

This is very interesting and useful (usually) feature. Sometimes, WordPress can partially match the URL depending on the rule. Than, it will find what URL should resolve to, and than generate proper URL for it, and redirect to it. So, you request one URL, and that gets replaced with some other URL. If you use category taxonomy in the URL, with hierarchy ending with post name like this:

http://www.example/parent-category/child-category/post-name/

If you make this request:

http://www.example/parent-category/post-name/

WordPress will find the post it needs, and than will determine that URL is not canonical as the rewrite rules require it to be, it will than generate full URL and redirect to it. But, if you don’t want this to happen, or you have additional rewrite rules for the post, canonical redirect will ignore all that and will redirect to URL it decides is correct. In that case, you must disable canonical redirect. To do that, you can use this PHP code:

remove_filter('template_redirect', 'redirect_canonical');

Conclusion

Handling custom rewrite rules is not easy, and very often you will run into conflicts. If you try to use same regular expression for your rule, you will remove default rule that was using same expression, and that will most likely break something. When working with rules, it is useful to have list of all rules in the system. You can see this list with GD Press Tools Pro debugger, or you can use few functions (check the debug rewrite rules tutorial, link at the bottom).

WordPress rewriter is very powerful, but by default it uses only a fraction of what it can do, since only basic rules are implemented, and if you need more, you must write code for that. The goal was to keep things simple in the core, and to allow freedom to customize things if needed. Not everyone will need so complex rewrite rules, and basic ones are enough. If you need more, you need to dig deeper or to use specialized plugins to achieve that.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/how-wordpress-url-rewriting-works/feed/ 8
How different caching methods work? http://www.dev4press.com/2012/tutorials/wordpress/practical/how-different-caching-methods-work/ http://www.dev4press.com/2012/tutorials/wordpress/practical/how-different-caching-methods-work/#comments Wed, 15 Feb 2012 11:00:32 +0000 MillaN http://www.dev4press.com/?p=13820 No matter how fast your server is, it is always a good idea to use different caching methods. It is important to understand how caching plugins work before you decide what is best solution for you based on how your website works and how much you want to gain with caching.

There are many cache plugins for WordPress. Some are only for a specific cache related use, and some implement all caching methods. If you want to use only a specific caching method, best solution is to get specialized plugin, if you need more – go with all in one solutions. Here on Dev4Press, cache is controlled by W3 Total Cache. Before we go into specific caching methods, there are some server features that can be used and that you may consider installing.

Why do you need to use cache?

Well, most important thing is speed. With one or more cache methods used, your website will be faster without expanding and upgrading the server. Faster website means that your visitors will get to information quicker, and slow websites are known to lose visitors that don’t want to wait long time for page to load. Also, search engines are taking website loading speed into account.

So, using cache will have some impact on the search engine rankings, will save you money on upgrading server and will improve visitors interaction.

Memcached

This is general purpose solution that is made to work across multiple servers for distributed storage of cached data. Data is stored in memory, and oldest values will be removed if allocated memory runs out. This is a good solution if you need to use multiple servers with a lot of memory and the servers are within the same network.

PHP Accelerators

There are several different accelerators available but most popular solutions are: APC, XCache and eAccelerator. They are storing compiled byte-code of PHP scripts into the memory. Normally, every time a script is executed PHP loads it and and compiles it. If you use accelerator, PHP runs pre-compiled byte-code from memory eliminating overhead of recompiling on each request. Here are some test results for loading of WordPress 3.3 with 3 different accelerators in use.

Accelerated WordPress 3.3 Loading

Accelerated WordPress 3.3 Loading

As you can see, use of accelerator for PHP will improve speed about 3 times. Accelerators can run on their own regardless of the cache plugin you decide to use, and you can’t use more than one accelerator in the same time. One more thing that accelerators can do is to work as object storage, and you can cache data also using functions.

Cache Methods

Page Cache

This is the most popular caching method available, and the method that brings biggest speed improvements. Normally, when page is requested, server loads WordPress and everything else needed, code is compiled and executed. So, for each request server needs to load PHP, to load all required files and compile and execute all. Depending on the server power this can take a different amount of resources and time to complete. If you use accelerators on the server this can be faster due to storing of compiled code. But, you can save even more.

Cache plugin is changing how the page is loaded. When a page is rendered with PHP and you get HTML to output to the browser, cache plugin saves that output as a plain HTML file. Files are stored in the folders that mimic the permalinks structure. Each file is stored as HTML and GZIPPED HTML (well, this depends on the plugin you use). Cache plugins need to modify HTACCESS, and add new rewrite rules. These rules check if the user is logged in and if it is not (checked through cookie), HTML file is loaded. So, when cached page is loaded PHP is not used at all and WordPress is not loaded! User gets simple HTML content from a single file and that is it.

This has some drawbacks: cached data remains the same for every visitor. Cache plugins allow you to rebuild cache from time to time to get new content in (once or twice a day typically, on busy websites once every couple of hours). Also, cache rebuild is run when new content or comment is published. Biggest problem is how to get dynamic data into the page even for visitors. Well, most common method is JavaScript and AJAX (my GD Star Rating plugin does that to get real rating values), and some cache plugins allow special tags in the code to markup the dynamic content. There are different implementation, but basic principle is the same for all cache plugin that use page caching method.

Typical gain in speed with page cache can be up to 10 times over normal non cache loading. Combined with some PHP Accelerator (for logged in users), you will get much faster loading. Accelerators have no impact on speed of page cache, since cached pages are HTML only.

Browser Cache

You can speed up loading on the client side only, by setting up proper request response headers, instructing browsers to store data for later and to load data from local storage on next visit. With this, loading of next pages on one website can be much faster if browser stores JavaScript, images or CSS files to reuse.

Through HTACCESS file you can set up handling of different file types by using expire time, cache control, entity tag and compression. Some WP cache plugin allow you to set this up for HTML, JavaScript, CSS and image files.

Minify Files

Typical page is not only HTML to be loaded by the browser. In most cases, to display the page, additional files are linked from the main HTML file, and that includes JavaScript, CSS and images. While you can’t change images that easily (it is always good practice to optimize them though some optimization software before using on website), you can make changes to JS and CSS files.

This process includes compression of JS and CSS files (special optimization of the code so it takes less space) and combining multiple files into one file. So, if you have 5 CSS files loaded on each page, with minify process you will get one file instead. With JavaScript typically you can get one or two files (one in header, other in footer). Same principle of compressing the code can be used for embedded JavaScript and CSS.

CDN: Content Delivery Network

Very important thing to speed up your website is to have some of the files loaded from some other server. If you have 20 images, JS and CSS files loaded for each page, you can set up CDN network that will allow you to have only main HTML file loaded from your server, while all other files loaded from CDN server. There are different methods to this, but must common one is called Mirror. You set up your CDN server (there are many companies offering this service), and you set up CNAME record on your server to point to the CDN server.

Change URL’s to all external files to use new CDN based URL and that’s it. CDN server will automatically pick files requested through CDN URL and store then on many storage locations (usually in different parts of the world), and when next time someone requests a file that is on CDN storage, it will be loaded from there, and not from your website. CDN can help offloading a large amount of traffic to your website generated by images, videos, JavaScript or CSS files.

But, process of changing URL’s can be very complicated, so cache plugins can do that for you automatically. With all plugins this is very easy to set up, and it depends on the CDN service you are using. CDN is not a free service, but the money you invest in this will pay off since you will save on your own server expanding, and you will have much faster website for your visitors.

Cache used on Dev4Press website

Server where Dev4Press is located uses eAccelerator for PHP. And it uses W3 Total Cache plugin with these cache methods active: page cache for visitors, minify JavaScript and CSS, browsers cache and CDN. Minify process helped by merging 7 JavaScript files into 2 files, and by merging 9 CSS files into 1 file. Typically on each page CDN is used to load 20-30 files.

With all the cache optimizations active a home page on Dev4Press.com (according to Pingdom Full Page Test) loads for 0.857 seconds for 71 requests and 660KB of page size. Without any of the optimizations, home page takes 17.5 seconds to load. That is 2042% gain, or 20 times faster with cache!

Conclusion

There are more cache methods available, but in my experience objects or database cache are not worth using due to problems it can cause and marginal speed gains.

How much you will gain with different cache methods depends on many things including server speed and configuration, use of CDN, cache plugin(s) you use… In some cases you can’t use all cache methods, and it is best to experiment until you find what works best for you. There are many plugins available, different CDN services to use. I hope that this article will help you understand how some of the cache methods work to decide what to use.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/how-different-caching-methods-work/feed/ 7
Canonical Redirect: Problem and Solutions http://www.dev4press.com/2012/tutorials/wordpress/practical/canonical-redirect-problem-and-solutions/ http://www.dev4press.com/2012/tutorials/wordpress/practical/canonical-redirect-problem-and-solutions/#comments Wed, 25 Jan 2012 12:30:05 +0000 MillaN http://www.dev4press.com/?p=13864 You have noticed how WordPress can fix and redirect incorrect and incomplete URL’s to your blog, and how different way you can link content will always redirect to one based on permalinks settings? That is called canonical redirect, and it is part of WordPress since version 2.3.

So, if you have permalinks structure for posts set to /%year%/%postname%/, and you try to reach post by it’s id with URL query argument, WordPress will resolve the request, and than redirect to permalinks based URL. So, if you have post with ID 10, and permalinks URL for it is something like this:

http://www.example.com/2012/my-post-is-here/

And you try to load the page with this:

http://www.example.com/?p=10

You will see that URL is redirected in browser to main permalinks based URL.

And this is really great feature. Even when you make a small mistake in the URL, there is a chance that canonical redirect will deal with it and show you what you were looking for. Good thing about this is that you will have only one valid URL to a page or a post, so search engines will not index same page with different URL. And nowadays, you can get penalty from search engines with duplicated content. So, canonical redirect is a very good thing to have.

But, there are cases where this is actually a bad thing, and you don’t want URL to be modified by WordPress like this. Some website owner run some third-party plugins that deal with canonical URL’s, or they simply don’t want it on. And, as with so many WordPress features you simply don’t have an option to turn it off. There is a simple one line code you can add to your theme functions.php or some other place to disable canonical redirect from loading:

remove_filter('template_redirect', 'redirect_canonical');

But, what if you want canonical redirect working, but not for every URL? Well, you can do that also, and it is not that complicated to do. What can be the reason for this? While developing GD Products Center plugin, I needed a very important feature: each post needed to have 5 pages, and I didn’t want numerical values for them, I wanted each page to have own URL. So, if the main post URL was something like this:

http://www.example.com/products/phone/samsung-galaxy-s2/

My added URL’s for it look like this:

http://www.example.com/products/phone/samsung-galaxy-s2/media/

http://www.example.com/products/phone/samsung-galaxy-s2/review/

http://www.example.com/products/phone/samsung-galaxy-s2/related/

Plugin was made to handle this extra element of the URL, and display proper content. But, canonical URL was not letting such URL through and it was always redirecting back to basic post URL. The only way to handle this, without disabling canonical redirect, is to attach a filter into that redirect function and prevent change in some cases. Filter you need for this is redirect_canonical.

So, the example for this would be:

add_filter('redirect_canonical', 'my_redirect_canonical', 10, 2);
function my_redirect_canonical($redirect_url, $requested_url) {
  if (is_singular('phone') {
    return $requested_url;
  } else {
    return $redirect_url;
  }
}

Filter parameter $redirect_url is canonical URL created by the canonical redirect function and $requested_url is originally requested URL. Within my_redirect_canonical function we need to decide if we want canonical URL or if we want to leave the original URL intact. This example here shows that we are checking if the post type for the request is for ‘phone’ custom post type. If it is, it will use original URL, if not it will redirect to canonical. You can change this to use different methods to check what URL to use.

So these are two methods to use to fully or partly disable canonical redirects. In most cases you need to leave this redirect method active, but it is good to know how to handle it if you need it gone, or at least partly disabled.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/canonical-redirect-problem-and-solutions/feed/ 0
WordPress development with NetBeans IDE http://www.dev4press.com/2012/tutorials/wordpress/wordpress-development-with-netbeans-ide/ http://www.dev4press.com/2012/tutorials/wordpress/wordpress-development-with-netbeans-ide/#comments Wed, 11 Jan 2012 15:00:44 +0000 MillaN http://www.dev4press.com/?p=13237 PHP is most popular programing language for web development, and WordPress one of the most important applications for PHP. Comfortable and powerful development environment is essential, and now, no other solution comes close to the power of NetBeans.

Latest NetBeans IDE from January 2012

Latest NetBeans IDE from January 2012

Intro to NetBeans IDE

Years ago, NetBeans started as Java development tool, but it grow much over the years. Now, NetBeans IDE support: Java, C/C++, Groovy and PHP with many more available through plugins. Depending on your development needs, you can download partial installation, and one of them is NetBeans IDE for PHP. Major elements of the IDE for PHP are: powerful code editor, projects, frameworks support, debugging, remote and local development, unit testing, phpDocumentator support, namespace support, mySQL integration, code coverage… Beside that, NetBeans IDE has complete support for: HTML, CSS, CSS3, JavaScript, AJAX and integration with popular toolkits (jQuery, Prototype…).

So, for WordPress development, you have everything you need in one powerful IDE. It is important to know that NetBeans IDE works on Windows, Linux and MacOS, and it requires Java JRE installed. Unlike the Eclipse that is also Java based, NetBeans is very fast and not resource hungry as you might expect from Java software, especially under Windows.

Setting up WordPress project

For local development you need, and most likely already have, local server setup where you keep your development websites. To use NetBeans you can use any such local server setup: DesktopServer, XAMPP… To make the best of the developing for WordPress, best thing is to add each your website as a separate project. That will include all WordPress files including wp-content with plugins and themes folder, so you can work on anything you need. Best thing about adding whole project like this is that NetBeans will scan the project and index WordPress function, classes and other elements. This scanning can take a couple of minutes for each project, and each time you start NetBeans, it will take a bit more time to check all projects for changes.

To add new project, open File menu, and click on New Project. Dialog likes this:

New Project

New Project

As you can see, you can start empty application, application from sources or remote server. Select one from existing sources and click next. New dialog appears. And you need to select where is your project. Browse for it, and select root folder where the WordPress installation is. It should look like the image:

Select source folder

Select source folder

Click open, and now you need to select PHP version and to give project a name. It is recommended to use PHP 5.1/5.2 for this.

Final project creation step

Final project creation step

Projects List

Projects List

Click Finish, and you are done. NetBeans will need one more minute to scan source for the project, and you will be ready to work. Your new project will be added to Projects list on the left (you can rearrange it). It is recommended to have each website as separate project.

Favorites Panel

Favorites Panel

If you work on plugins or themes in one WordPress installation, you can make it easier, and add each plugin or theme you need into Favorites panel. This will help you find your work easier without going through whole projects list. To do this, simply right-click on the folder in the projects panel, and select from Tools menu option Add to Favorites. Favorites look with the Navigator is on the image on the right.

Navigator shows all identifiable elements in the now open file for easier navigation through the code.

Powerful editor

Once you have set up the projects you want to use, you can first of all, use autocomplete. If you are in PHP context editing, you will get info on all found functions (both default PHP and found in the code). If you are in JavaScript or CSS editing context, it will work the same way. Image here shows what happens if you start typing ‘wp_admin_c’. You will get list of possible functions and all function versions in regard to arguments, and above you will see documentation for selected function.

Autocomplete and suggestions

Autocomplete and suggestions

If you need to navigate through code by following functions, you can use context menu and option Navigate, or you can use hover over the function, class or variable name with CTRL key pressed, and you will get item documentation. If you click, you will be taken to declaration. Code folding works great with any type of code and will help you working with large files. Also, there are plenty of options available through top and context menus.

Code navigation and quick help

Code navigation and quick help

NetBeans support phpDocumentator specification, and to add it, position cursor in the line before function or class declaration starts, start the line with /** hit enter, and you will get all comment containing parameters, globals and return found in the function or class.

If you need to work with CSS, JavaScript and HTML in your files, you can do everything (or almost) with NetBeans. CSS editor is very powerful, and I have stopped using any other external editor for that, and from 7.1 version, it supports CSS3.

File Version History

File Version History

Support for SVN, GIT, Mercurial

If you are using some versioning  system (Subversion or Git for instance), NetBeans will allow you to work with repositories directly and to show you changes to files, to make updates or send changes to server.

Color coded changes in editor

Color coded changes in editor

All changes made are color coded in the editor, but you also have History look that will show how the code looked before and after modification with access to all historical changes data for both local and versioning system changes.

Editor uses colors to mark deleted (red), new (green) and edited (blue) lines of code. Navigation can be done directly by clicking on the position on the right side of the editor. There are many useful things to help with navigation including markers, all found on the editor toolbar.

Debug whole WordPress website

Yes, you can do that. I will not go into details on how to set up your environment for debugging, there is a in detail article on NetBeans website about this: How to configure XDebug. Anything you expect from debugger you can find here. You can start debug of the whole project, and that is what you must do when developing for WordPress (regardless if you make theme or plugin), because WordPress needs to load the way it usually does, so always use Debug Project option for this. In debug mode, you will get additional panels tracking the process and you can use break points also (simply click on the line number to add red debug point).

What’s next?

This is only introduction in using NetBeans IDE for WordPress development, just to get you started. It can take you few days to take everything in and to discover what can be done with this great program, but it will be worth it. You can easily replace all your other editors with this one and make your development process more streamlined and confined within one program.

Download NetBeans IDE:
http://netbeans.org/downloads/

]]>
http://www.dev4press.com/2012/tutorials/wordpress/wordpress-development-with-netbeans-ide/feed/ 1
Debug WordPress rewrite rules matching http://www.dev4press.com/2012/tutorials/wordpress/practical/debug-wordpress-rewrite-rules-matching/ http://www.dev4press.com/2012/tutorials/wordpress/practical/debug-wordpress-rewrite-rules-matching/#comments Fri, 06 Jan 2012 23:05:46 +0000 MillaN http://www.dev4press.com/?p=13093 With introduction of custom post types, additional templates WordPress loads and maybe custom rewrite rules websites can use, it can be a bit confusing what happens when WP loads and resolves the URL. Sometimes you will end up on wrong page, and here is to find out why.

Intro

If you don’t use permalinks structure for URL’s, you can skip this article. All this matters only when permalinks structure is on. And since most websites use them, it is useful to know how the pretty URL is resolved. When URL is parsed by WordPress, a long list of rewrite rules is used to match the URL (using regular expressions) to a query that WordPress can than understand and use to load and display data. If two rules are conflicted, the one with higher priority is used. If no rule is matched, WordPress will load 404 page. If the rule is matched, but the query returns no results, again 404 page will be displayed, this means that URL request was invalid.

If you have complex data structure with many post types, if you use even custom rewrite rules, you can end up with the 404 pages very often, if the rewrite rules are not resolved properly. In most cases, every URL request will resolve as a page if all other rewrite rules fail.

Get the list of all rewrite rules

You can always display list of all rewrite rules registered in WordPress. There is a simple function that can display all the rules in the table form:

function dev4press_debug_rewrite_rules() {
  global $wp_rewrite;
  echo '<div>';
  if (!empty($wp_rewrite->rules)) {
    echo '<h5>Rewrite Rules</h5>';
    echo '<table><thead><tr>';
    echo '<td>Rule</td><td>Rewrite</td>';
    echo '</tr></thead><tbody>';
    foreach ($wp_rewrite->rules as $name => $value) {
      echo '<tr><td>'.$name.'</td><td>'.$value.'</td></tr>';
    }
    echo '</tbody></table>';
  } else {
    echo 'No rules defined.';
  }
  echo '</div>';
}

Add the function to your code, and call it inside any theme template to print the list of all rewrite rules. Order of rules are also the priority, top rules are with highest priority. Reading the list can be confusing if you don’t understand how the URL rewrite in WordPress works, and it is more useful to developers for debugging.

Display resolved rewrite rule and loaded template

Now, we can use another function to show us how WordPress resolved the URL request and why the template is loaded:

function dev4press_debug_page_request() {
  global $wp, $template;
  define("D4P_EOL", "\r\n");

  echo '<!-- Request: ';
  echo empty($wp->request) ? "None" : esc_html($wp->request);
  echo ' -->'.D4P_EOL;
  echo '<!-- Matched Rewrite Rule: ';
  echo empty($wp->matched_rule) ? None : esc_html($wp->matched_rule);
  echo ' -->'.D4P_EOL;
  echo '<!-- Matched Rewrite Query: ';
  echo empty($wp->matched_query) ? "None" : esc_html($wp->matched_query);
  echo ' -->'.D4P_EOL;
  echo '<!-- Loaded Template: ';
  echo basename($template);
  echo ' -->'.D4P_EOL;
}
Debug Rewrite Rules in header

Debug Rewrite Rules in header

Best way to use this is to add the function into your code (functions.php in the theme), and to call it in the theme header.php template, best to do it on top, right after HEAD tag. Look at the image on the right for the example.

When you do that, whenever you load new page in the browser, the debug info about rewrite rule matched will be embedded as a comment on top of the header. And if you end up on 404 page, you can see why, what happened to resolved rule to do that.

Images bellow shows example output for this debug info. Request is always displayed without the domain name. First example is success matching of a request to a post, and loading of single.php template. First line is request, second line matched rule (regular expression), and when the rule is matched, request is transformed to a query (line 3). This query is something WordPress can interpret and load via proper template. Based on the query, WordPress creates a query object that is used to get the data and determine template to load (last line).

Matching Hello World single post

Matching Hello World single post

Next image is a custom rewrite rule for my GD Products Center plugin archive page that mixes both custom post type and taxonomy.

Matching archive for custom rewrite rule

Matching archive for custom rewrite rule

Third example is for the URL that can’t be resolved properly. When all rules in WP fail, last one remaining is a single page rule. And this example has triggered that, and practically the whole request is matched as name for the page. And since such page doesn’t exists in the system, 404 template is loaded.

Matching ended up as a page that don't exits giving 404

Matching ended up as a page that don't exits giving 404

If you use Dev4Press plugins this is already built-in some

If you use GD Press Tools Pro, you have a debugger module built-in that can display all the data we discussed here and more. If you use GD Custom Posts and Taxonomies Tools Pro (these functions: gdtt_debug_page_request_comment, gdtt_debug_rewrite_rules, gdtt_debug_page_request) or GD Products Center (these functions:  gdpc_debug_page_request_comment, gdpc_debug_rewrite_rules, gdpc_debug_page_request), so check the documentation for more details. And it will be added to xScape framework soon, and it will be easy to turn on or off.

Conclusion

So, now you can easily find out why WordPress loaded a page for every of the URL requests and find out likely cause to end up on the 404 page. This is also important when working with custom rewrite rules that can be in conflict and can cause 404 page to load.

]]>
http://www.dev4press.com/2012/tutorials/wordpress/practical/debug-wordpress-rewrite-rules-matching/feed/ 2
How to optimize plugin loading http://www.dev4press.com/2011/tutorials/wordpress/practical/how-to-optimize-plugin-loading/ http://www.dev4press.com/2011/tutorials/wordpress/practical/how-to-optimize-plugin-loading/#comments Wed, 28 Dec 2011 13:50:07 +0000 MillaN http://www.dev4press.com/?p=11877 Few weeks ago I have tested 35 plugins to find how they affect WordPress in terms of loading and resource usage. What can plugin author do to make plugin loading faster, to use less memory and to lower its impact on website loading? There are several things to consider.

Notice: This tutorial is primarily for plugin developers, but it can be useful reading for anyone working with WordPress to better understand how plugins load and what can be done to improve it.

Intro

Before we go on, I recommend you to take a look at the article with test results. I know that many readers were surprised by the results, considering how some high-profile plugins scored very low and ended up in the bad optimized plugins category. Optimization will take these plugins one step further, showing that author cares about used resources (most WordPress websites are on shared hosting, and resources can be very limited), and that author understands that optimization is as important as adding features and making plugin look pretty.

So, what plugin authors can do to make their plugins better, how to optimize their loading, resource usage and with that speed? Before I list recommendations for this, here is a small analysis of how plugins are loaded.

Plugins Loading

One of the early steps in the WordPress loading is to load plugins. WordPress will get the list of all active plugins and it simply use PHP include function to load main plugin file. That main plugin file can contain the plugin (for smaller plugins or widgets), or it can be used as plugin loader to initialize plugin, or it can be the mix of the two. WordPress will do this for every single page, it will always include active plugins.

Even if the plugin is small, this can be an issue. For instance, my GD Unit Converter plugin was used in the benchmark article. This plugin adds a widget on the admin dashboard, and that’s it. But, if you look at test results it was using 0.5MB on admin side and 0.4MB on the front end side. And it was doing nothing on front end side! So, I changed the main plugin file to act as a loader only. It will check if we are on admin side, and it will load another file that actually contains plugin. If we are on front end side, it will do nothing. After this optimization, on front end side plugin uses now 20KB, that is 95% memory saved. That is amazing gain, but you can’t expect such results for every plugin.

If you look at the test results again, even smallest plugins will use 0.4MB to 0.5MB. Imagine that you have 20 such plugins, and if all 20 of them save just 0.2MB, that will lower memory usage by 4MB, and will improve speed a bit. That might not look like a lot, but trust me, it will make a difference, especially for shared hosting websites.

Most plugins have a specific usage, and that requires plugin to be loaded only on some pages. In some cases you will need parts of the plugin functionalities loaded on every page. It can be very complicated to decide the need for plugin on each admin or front end page. But, you need to recognize what parts of the plugin are always needed, and what parts will be specific to some of the pages. That basic analysis will help you to decide what pieces of code go into separate files. If your plugin is only for the administration, it doesn’t need to be loaded on the front end. It is very simple to check this in the loader file and to prevent loading of the rest of the plugin.

If your plugin ads administration side pages or forms, you will need to load CSS styles or JavaScript files. Too many plugins these days are making a very big mistake of loading these files on every administration page without checking if the page belongs to the plugin. That will most likely break other plugins or change the styling for other plugins, or even WordPress. This is one of the things that must be optimized and done properly.

Files and folders organization

One of the most important things with any plugin, is organization of files and folders with code, CSS, images, JavaScript. When you make right structure for files and folders, you will make it easier to make future changes and perform maintenance.

  1. Code should be split into files according to functionalities. Many plugins don’t have that strict code separation, and they end up with large files with functions and classes thrown in. This makes later changes and maintenance harder, because code has no logical structure or order. Also, big files will use more memory, even if most of its functionality will not be used at all.

    Code Folders

    Code Folders

  2. HTML forms should be separated from files with code. These forms will be loaded only on some pages, and they will contain mostly HTML markup code (they can contain PHP code, and usually do, but only used to fill HTML elements with data), and they should be kept outside of the main plugin code.
  3. Create few folders for different files types for your plugin. Main plugin code should go in one folder, files with HTML forms should go into another folder, CSS styles and JavaScript should go in own folder and images should go in own folders. On the image on the right you can see a folder structure for one of my plugins. I like adding extra sub folders for ‘code’ and ‘forms’ depending on how many forms there are or how much code. In ‘code’ folder it is recommended to have another level of folders if you have a lot of files.
  4. If you have a lot of JavaScript or CSS files, it is good to have source versions for them as well as minified versions. This way they will be lighter on load, and you will have source versions for debugging and development.

Preparing for Optimization

To make the most of the loading process, you need to know what page are you on. Based on that you can perform different operation and load different files. Make sure you set a variable with the page file name or some other identification. On admin side, WordPress pages are identified by the file name loaded. Your own plugin pages can be identified by the ‘page’ variable from the URL request . To get the name of the file, name of the page and more, you can use this code:

$_current_file = end(explode("/", $_SERVER["PHP_SELF"]));
$_current_page = isset($_GET["page"]) ?  $_GET["page"] : "";
$_doing_ajax = defined("DOING_AJAX") && DOING_AJAX;
$_doing_cron = defined("DOING_CRON") && DOING_CRON;

Based on this values you can pretty much know exactly which page is loaded, and what you need from your plugin to load. This can be executed in the main/loader plugin file. I have added two more variables to determine if the page is loaded for AJAX handling or while doing Cron job.

Optimization Recommendations

Here are some of the important recommendations you should follow:

  1. Analyze your plugin code, and decide what you need loaded on admin side, what on front end, and what on both. When you do that, you can go further and decide what you need loaded on all admin pages, and what on some of them (your plugin panels). Based on that, you will end up with many smaller files. Make some convenient naming scheme so that you can easily find files and use them in loader.
  2. Always use main plugin file as loader. Even for simple plugins, this is best solution because you will have easier time later to expand the plugin. Don’t keep any code that is used by the plugin there, only decide what parts of the plugin you need to load.
  3. Try to use classes as much as you can. Also, try to have only one class in a file, or at least put classes that depend on each other in one file. Use some logical naming convention for files, so that name gives you quick association to the class inside. PHP can help you with auto loading of files based on the required class, and you can find more info on that at the end of this tutorial.
  4. Separate all AJAX handling code into own file. When your plugin on the server-side needs to handle AJAX requests, don’t add all that into file that is always loaded. It is easy to decide if the WordPress is loading to handle AJAX request, and only then load AJAX handling file. This goes only if the AJAX is handled by the WordPress admin-ajax.php file.
  5. Always handle all AJAX calls through WordPress admin-ajax.php. This will save you a lot of headaches, and it can be used for both front end and admin side. Making your own handler file for AJAX is never good idea. If you need help with using admin-ajax.php, here is a good post in the WordPress.org Codex on using AJAX in plugins.
  6. Separate all Cron jobs handling code into own file. Similar to AJAX handling, Cron jobs executions are run in own page/thread call, and you can always determine if that is the case. If you have cron jobs in your plugin, move all its handling functions and classes into files that will be loaded only when Cron job is executed.
  7. Any other code elements that are needed for some panels only, or in some specific cases, keep in own file(s) and load them only when needed. This can be code that handles individual panels, AJAX handling, CRON handling, saving data… The better you identify what you need and make smaller files to load when needed, you will get better optimized files.
  8. Handle all plugin settings through WordPress options database table through get_option/update_option functions (or get_site_option/update_site_option for multisite network wide settings). Never save individual settings as separate options, this can create a mess and will be hard to update and maintain. Put all your settings in one or more array’s (depending on the scope of settings you have). These settings are all loaded with a single SQL query when WordPress loads, and you have them ready when your plugin loads.

PHP Auto Loading

PHP has several methods to trigger automatic loading of files, based on the required code. If you split your code into classes, you can set up autoload functions that will do loading of files based on the class name. This can be very good solution for a plugin that has many classes used as modules, or used only in some cases. It is recommended to have one class in one file. More info about this you can find here: Autoloading Classes on PHP.net. Comments on that page have some really great examples on how the auto loading works.

GD Press Tools Pro Debugger: Snapshots

GD Press Tools Pro Debugger: Snapshots

Measuring the optimization

My GD Press Tools Pro plugin can be used to debug and track WordPress loading. Tracker in this plugin has functions you can use to create snapshots that will contain used memory, hooks, SQL queries and time. You can use these functions in your code to measure how much resources some are used during different stages in the loading process. Plugin has a lot of other things to help you debug the code, find errors, track loading, track WordPress query, enqueued scripts and styles and much more.

There are some other plugins you can use to debug WordPress, but no other plugin allows tracking of the loading and the level of detail as GD Press Tools has.

Conclusion

There are many things you can do to optimize your plugin to use less memory and to load faster, and to have less impact on overall loading of WordPress. This article doesn’t cover everything and you will not be able to use all the recommendations for every plugin. But, good analysis, good code splitting and loading and tracking your optimization progress will always give you good results. Better optimized plugin is later easier to support and expand.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/how-to-optimize-plugin-loading/feed/ 22
Choosing mySQL Database Engine: myISAM or InnoDB? http://www.dev4press.com/2011/tutorials/wordpress/practical/choosing-mysql-database-engine-myisam-or-innodb/ http://www.dev4press.com/2011/tutorials/wordpress/practical/choosing-mysql-database-engine-myisam-or-innodb/#comments Wed, 26 Oct 2011 21:13:57 +0000 MillaN http://www.dev4press.com/?p=10743 WordPress is designed to run only on MySQL database. So, optimizing MySQL is very important thing if you want to run WordPress as fast as possible on the hardware you use. But, that might not be as straightforward as you may thing, considering that MySQL can used many storage engines.

Since MySQL 5.0, there are 10 (yes, ten) storage engines in MySQL. Before MySQL 5.5 was released, MyISAM was default storage engine, and when you create a new table without specifying engine, table would use MyISAM engine. After you upgrade to MySQL 5.5, default engine is now InnoDB. Great thing about MySQL is that you can use different storage engines for each table.

MyISAM

This is old(est) storage engine in MySQL and most commonly used. This is engine that is easy to setup (no foreign key relationships between tables, or design problems). It is very good in read related operations and it supports full text indexing. But, it has many disadvantages: no transaction support, no data integrity check (no strict table relations) and it supports only full table lock making it slower if you need to update or insert data, because for each update or insert, whole table will be locked making it unavailable for other queries. Because of this, MyISAM is on the average good for most of the WordPress tables. MyISAM works well out of the box, and it doesn’t need too much optimization. Even with optimization, you can’t gain much in terms of performance over default setup.

MyISAM is not very reliable in case of hardware failure, process shutdown or some other disruption. This will almost always cause data corruption depending on the last operations run.

InnoDB

This is relatively new engine and it supports transactions, it is very fast in insert or update operations because it supports row locking allowing for multiple operations over same table and it supports foreign keys for table relations. And all that makes InnoDB great when data integrity is important issue. But, designing tables with foreign key constrains is not always simple, it doesn’t support full text indexing and it needs more resources (memory) that MyISAM. Also, you need to spend some time optimizing this engine. Depending on the level of optimization and hardware used, InnoDB can be set to run very fast, some report even 20 times faster than default setup.

InnoDB doesn’t have constant size for the table. Even when you get table sizes, you need to know that the values returned are only estimates. This comes from different way InnoDB handles data, and because of that it needs more space for data than MyISAM. But, InnoDB is very reliable due to transactional nature of data operations, and makes it very good choice for systems where backup operation are essential and often needed. InnoDB tables are reliable and has many safety measures implemented to make sure that data remains safe.

What engine to choose?

Well, this is not easy thing to answer. Since InnoDB is now default engine (MySQL 5.5), when you install new WordPress on server running latest MySQL, you will most likely get all InnoDB tables. If you have powerful server with a lot of memory, you will not notice any slowdowns (if InnoDB is set properly), and for many operations you may notice speed improvements.

If you have all MyISAM engine tables in the database, you might consider switching some of them to InnoDB engine. There is no right answer here, and it all depends on what you need from your database. By default, WordPress doesn’t use full text indexing, so it makes it OK to use InnoDB. If you need more data reliability, InnoDB is the way to go. Since WordPress doesn’t use foreign keys for table relations, engine choice is also not important, both will work well.

For normal websites, with no big traffic, engine is not that important. Speed issues comes into play if you have a lot of traffic on your website. In that case, InnoDB for some tables is a good idea if those tables need a lot of updating. Typically, such tables can be wp_options, wp_usermeta, wp_comments tables. Also, if you have some custom tables (used for visits tracking or other logging methods), these tables should be InnoDB tables considering that writing with InnoDB is row locked allowing for much more threads to use the table than with MyISAM. Also you must consider that InnoDB will need more resources than MyISAM, so make sure that you have a lot of memory, or even to use separate server for MySQL only. If you want to use full-text search for some tables, there is no choice, you must use MyISAM.

Best thing to do is to test both engines for different tables over a period (again, consider your server resources), and to find the balance setting some tables with InnoDB and some with MyISAM. Also, make sure to check MySQL settings for both engine types and consult system administrator to make sure that both are configured for best performance (this is very important for InnoDB). finding the right balance between these two engines may gain you extra speed. Using only one engine is a good idea if you have some replication environment where different engines can affect replication performance. In such case InnoDB has proven as a better choice.

I think that WordPress in next major revision (maybe for 3.4 or 3.5) should consider setting engines for each table based on the table primary role. That would need some in-depth testing, but it would be worth having best choice of engines from the get go.

If you need some more in-depth information about engines optimization and engine choice, I recommend that you check following websites:

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/choosing-mysql-database-engine-myisam-or-innodb/feed/ 1
Add rich text editor(s)… the right way http://www.dev4press.com/2011/tutorials/wordpress/tips/add-rich-text-editors-the-right-way/ http://www.dev4press.com/2011/tutorials/wordpress/tips/add-rich-text-editors-the-right-way/#comments Thu, 13 Oct 2011 21:15:48 +0000 MillaN http://www.dev4press.com/?p=10351 Adding rich text editor, like the one used for the post editor, was a really big problem in WordPress. And while there were some ways to do it, it was never working as you would expect it, there were too many issues and conflicts. But, with WordPress 3.3, all that changes.

Two editors on the same screen

Two editors on the same screen

In my earlier article on the subject (Add rich text editor to your plugin), I have described a method on how to add single, fully working rich text editor to any plugin. And, for that specific purpose, that method was working great. But, if you needed 2 editors on the same page, or if you needed to add editor in the meta box on the post editor page, it wasn’t working. There are other methods on the internet to do this, but none of the is actually fully working: all involve some hacking, and all were messy to use.

Now, in WordPress 3.3 there is a new way of doing this. Whole editor code is updated to allow more than one editor instance on any admin screen (still haven’t had a chance to see how to make this work on the front end), including post editor page. And, all that is needed is one single function:

wp_editor($content, $editor_id, $settings = array());

First value is actual content you want to display in editor when it is displayed. Second one is very important, and this needs to be unique since it is used as an ID for the editor control. Last value can be skipped, but it can be used to add more settings to the editor. There are many settings you can add with the last parameter, and some of them are not working now (WP 3.3 Beta 1). Here are some of the settings you will need and use:

  • wpautop: enable the default WordPress content formatting, active by default.
  • media_buttons: show or hide upload insert button, active by default.
  • textarea_name: name for the editor element. By default it is same as $editor_id you pass to the function. This is name used to identify the editor in the $_POST for saving purpose.
  • textarea_rows: number of rows, size of the editor.
  • editor_class: extra CSS class to add to the editor.

All the other settings can be found in WP_Editor class, for editor method. So typical example of how to use this would be:

$args = array("textarea_rows" => 5, "textarea_name" => "editor_content_1", "editor_class" => "my_editor_custom");
wp_editor("My editor content", "my_editor_1", $args);

And that is all you need. You can play with settings to see how this works. New editor model is done really well, and so far in the current Beta works pretty much as expected. There will be some changes until final 3.3 is released, so check this post out for all the changes in the editor implementation.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/tips/add-rich-text-editors-the-right-way/feed/ 20
Exclude subcategories from RSS feed http://www.dev4press.com/2011/tutorials/wordpress/tips/exclude-subcategories-from-rss-feed/ http://www.dev4press.com/2011/tutorials/wordpress/tips/exclude-subcategories-from-rss-feed/#comments Sat, 01 Oct 2011 19:15:08 +0000 MillaN http://www.dev4press.com/?p=9672 WordPress WP_Query class is used to get posts for, basically, everything. And this class is very, very complicated. It has a long list of supported query variables, filters and actions to control the process. But, even with all that, there are some limitations in conventional methods of use.

If you want to exclude posts that belong to more than one category, you can use query variable called category__not_in. You need to specify array with category ID’s to exclude. But, if you want to exclude sub categories of the categories you have listed, this will no do. To exclude sub categories also, there is a little piece of code you can use. This is very useful for RSS feeds, since you can have better control over posts available in the feed.

First, here is normal example where we want to exclude posts from 4 different categories. First piece of code is classic example to get posts:

$args = array("category__not_in" => array(2, 7, 43, 66));
$posts = get_posts($args);

And the other one is to do this with RSS feed:

add_filter("pre_get_posts", array(&$this, "d4p_rss_query"));
function d4p_rss_query($query) {
  if ($query->is_feed) {
    $cats = array(2, 7, 43, 66);
    $query->set("category__not_in", $cats);
  }
  return $query;
}

But, if these 4 categories have subcategories, than you have a problem, posts in the sub categories will still be in the results. Here is the simple code to change that.

$cats = array(2, 7, 43, 66);
$main_cats = array(2, 7, 43, 66);
foreach ($main_cats as $cat) {
  $cats = array_merge($cats, get_term_children($cat, "category"));
}
$args = array("category__not_in" => $cats);
$posts = get_posts($args);

First and second line both contain same list of categories. This is to make sure that main categories are also included, and that we can go through the list to get children categories in lines 3 to 5. Again, here is the code for RSS feed.

add_filter("pre_get_posts", array(&$this, "d4p_rss_query"));
function d4p_rss_query($query) {
  if ($query->is_feed) {
    $cats = array(2, 7, 43, 66);
    $main_cats = array(2, 7, 43, 66);
    foreach ($main_cats as $cat) {
      $cats = array_merge($cats, get_term_children($cat, "category"));
    }
    $query->set("category__not_in", $cats);
  }
  return $query;
}

You can modify $args further with extra parameters, or you can use it with query_posts() function or other query methods. This same methods is used here on Dev4Press to control RSS feeds.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/tips/exclude-subcategories-from-rss-feed/feed/ 1
Getting PHP errors from server http://www.dev4press.com/2011/tutorials/wordpress/practical/getting-php-errors-from-server/ http://www.dev4press.com/2011/tutorials/wordpress/practical/getting-php-errors-from-server/#comments Tue, 23 Aug 2011 22:05:25 +0000 MillaN http://www.dev4press.com/?p=6536 The most important step in debugging problems with the website (WordPess powered or any other) is to be able to get errors logged on the server side. This is not always as straightforward process as you might think and there are different approaches to have and find error logs.

Any web software, and this include WordPress and plugins for it will work as you expect it in most cases. But, no matter how good the code for plugins is, it can happen that some server setups can break it. Also, other plugins can cause problems. Best way to determine the problem is to get server side errors. Most servers are by default set to log all errors into the file, and to hide them from the user. With shared hosting, you usually can’t control this, and if the errors are not logged, you must consult your hosting company support to enable error logging. If you have own server (VPS or dedicated) you have full access, and you should be able to disable or enable error logs when you need them. I can’t get into details on this, it depends on the server. Error logs can be PHP specific, or they can contain all sorts of errors merged into same files.

Most used control panels for servers are cPanel and Plesk, and here is the information how to get logs from these two. They allow you to see all errors compiled in one place. But, PHP can be set to save error logs in folders where the errors have occurred, so you will need to go through website folders to find these files. They are usually named error_log.

Plesk

Plesk

Plesk

Plesk is great control panel that works with Linux and Windows servers. To get error logs in Plesk, open Websites and Domains tab (this can differ, depending on Plesk version and edition), and usually hidden are advanced operations. When you open them, you will see Logs as on the image on the right.

When you open Logs, you will get list of websites. For each website you have separate set of logs. Select website you want and you will get a long (usually) list of log files. Find file named error_log and that is the latest one. Old error log files are usually archived.

And, you can set Plesk to send you archived error logs to your email each day or each week.

cPanel

cPanel

cPanel

cPanel is most popular control panel for Linux hosted websites. To get the error logs, you need to open Advanced Statistics panel. There you should have Error Log button. Once you click on it, you will get error logs for all websites you have installed, or each individual error log (depends on the server configuration). If there is not Error Log button, or if there are no error logs, it’s most likely that error logging is disabled on your server.

WordPress error logging

If this doesn’t help, and you didn’t found error logs, you can set up WordPress to save errors into file. To do this, you need to modify the wp-config.php file.

define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);

First line will activate error reporting for all types of errors including strict and deprecated errors. Second define will activate displaying errors on the screen. Last line will activate logging errors into the file. This file will be debug.txt in your wp-content folder, so make sure that that folder is writable for WordPress. This way, you will get errors in the file that is easy to find.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/getting-php-errors-from-server/feed/ 0
WordPress Debug mode: Benefits and Pitfalls http://www.dev4press.com/2011/tutorials/wordpress/practical/wordpress-debug-mode-benefits-and-pitfalls/ http://www.dev4press.com/2011/tutorials/wordpress/practical/wordpress-debug-mode-benefits-and-pitfalls/#comments Sun, 24 Jul 2011 22:10:04 +0000 MillaN http://www.dev4press.com/?p=4999 Developers know how to best use debug in WordPress and it’s WP_DEBUG constant to get through potential problems and bugs their code might have. But, for regular users, using debug mode can be a very much confusing and can cause more problems than it can help solve.

PHP Errors

Before we go on, here is the short overview of common PHP errors you can find while running any PHP code, including WordPress. Beside these 4, there are some 8 or 9 more error types, most of which you will not see if your PHP is installed properly and is not unstable build.

  1. Notices: These errors are trivial and non-critical, and these errors are not displayed by default and they can’t stop code execution (variable not defined yet, for example).
  2. Warnings: These are errors that also don’t stop code execution, but they are displayed to user since they point to a code problem that can cause further issues (failed to include file, for example).
  3. Fatal Errors: These are critical errors that are displayed and that will also stop code execution. These errors point to a problem that prevents further execution (missing class or function, for example).
  4. Parse Errors: These are critical errors that are caused by invalid PHP code (missing semi colons or some other unexpected characters).

WordPress Error Handling

By default WordPress debug mode is disabled. Error handling and display depends on the server settings. In most cases this means that errors will not be displayed (even fatal errors), but they should be logged into file (again, depends on server settings, and it can happen that logging of errors is disabled).

To enable WP debug mode, you need to add WP_DEBUG constant set to TRUE into wp-config.php file. Recently, wp-config.php has definition for this constant included and set to FALSE. So, you need to have this line in your wp-config.php:

define('WP_DEBUG', true);

This will activate error reporting for all types of errors including strict and deprecated errors. There are two more debug constants that can be used if WP_DEBUG is active:

define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);

First one will activate (or force) displaying of errors on the screen. Second one will activate logging errors into the file. This file will be debug.txt in your wp-content folder.

Why use WP Debug mode?

By default, if you don’t make changes to WP core files, and you don’t have any plugins or third party themes, active WP debug mode is not going to make any difference and you will see no errors. But, as soon as you start adding plugins and change theme, things will get very, very different.

Main reason for debug mode is to discover errors thrown by the PHP code. If you are working with development installation (your localhost, or server test enviroment), it’s highly recommended to use WP Debug mode. If you write your own plugins or themes, it is essential to use it.

Debug mode is on, what now?

For live environments, WP Debug mode should be used only if you get broken website or no access to it at all. Typical case is that you open your website (any page or only some pages), and instead of content you either get 505 internal server error, or you get blank screen. In most cases, if server is set correctly, errors will be logged in any case and you need to check error logs to find out what the problem is. But, if that is not the case, enable WP Debug mode through wp-config.php, and you will be able to see what the problem is.

When you get the error, that error includes path to the file where the error has happened. In 90% of the cases that is some plugin that is causing problem. But, very often, you will see that error is in some WordPress file in wp-admin or wp-includes folders. If used normally, there should be no errors there, so that points again to a plugin that uses some WP function or class the wrong way. Debugging in that case can be a bit harder, but this will always (well, almost always) help:

  1. Disable all plugins.
  2. If the problem is still there, theme is causing it, disable it to check.
  3. If the theme is not the problem enable plugins one by one.
  4. After enabling a plugin try to repeat the operation that caused the error.
  5. Once you see the error again, last plugin you activated is at fault.
  6. Contact plugin author with the error message and description of what you were trying to do.
  7. Wait for the solution… Or
  8. Try to fix it yourself, if you are developer or have PHP experience.

Fatal Error: Out of Memory…

Typical errors you will discover like this, include famous PHP is Out of Memory error, that many users don’t understand at all. When you see this error don’t panic: you only need to increase available memory for PHP. In most cases server was configured to use 16M or 32M (standard values), but WordPress with several plugins will need more. So typically, 64M should be enough for anything. If you have more than 40-50 plugins, you could need more than that.

But, this error can also point to a memory leak in some plugins. If you increase memory to 128M or more, and you have 10-15 plugins, a plugin or theme you are using is bad, and it leaks memory most likely due some endless loop in the code or greedy SQL queries that return too many results or for some other reason. Detecting which plugin leaks memory, usually is easy to see. If you look at full error description you will see where the problem occurred, and that will include path to the file, and that path includes the folder name of the plugin (or theme). Again, memory leak is not the same as having just too little memory allocated. Any WP installation should use 64M to 128M, more than that can point to a leak.

Here are several methods for increasing PHP memory:
http://www.dev4press.co….rease-php-available-memory/

And once again, hosting company comes to the stage, because some of them will not allow you to change PHP memory on your own (or at all, yes I have seen few of those), and you have to wait for them to do it. In this case, there is only one solution: change your hosting company. Whatever you are paying for hosting, I am sure that there are at least 5 other companies with same prices that will not limit you in using some basic things like memory allocated to PHP.

Debug Notices

Debug Notices

And now Pitfalls

Yes, this all looks great, enable WP Debug mode and you will find the problem. And what if you find to many problems? Finding fatal errors is one thing, but enabling debug mode will open the door for all other error types to surface, even if they are not critical. Take a look at the screenshot on the right, and you will see all sorts of errors: notices, deprecated use and warning. They are not critical, but when debug mode is on, you will see it all, and this can make debug almost impossible.

From experience 95% of all plugins and themes (this can be applied to commercial ones) for WordPress will generate these non critical errors when used. Most developers don’t care about these, and they will leave in the code, and that points to another problem: if they didn’t care to fix these non critical errors and warnings, what else is in their code that can be a real problem? As I said before, development should be done with debug mode on, and these notices will be visible. If they left them in the code, they didn’t see them, and that means they didn’t used debug mode at all. For my part I try to fix every notice and warning I have in my plugins (even most minor one: initializing variables and arrays), and my plugins will not throw such notices (if you find any that I maybe missed, please report it).

So, you activate debug mode, and you find yourself drowning in the pool of notices all over the screen, and you have no idea where to begin. You can go through each plugin code to fix the problems, but that is not really good idea. Waiting for developers to fix own plugins? Well, that can take a long time… After all this, you see that debug mode can be a tricky to use since it can be rendered useless when you have old and not maintained or not very well written plugins in the first place. You can combine display and logging of errors, but for non developers and less experienced users, debug mode can be impossible to use.

There must be some easier way?

How to use debug mode and how to get these error messages displayed without messing with the page content? Thankfully there is a way. PHP provides methods to override default error handlers and to ‘hijack’ their output to hide it or use for some other purpose. You are not going to write own handlers every time, best is to use a plugin that will do that for you. As far as I know, there are 2 free plugins that can do this: Debug Bar and BlackBox Debug Bar. If I were to use any of them, that would be BlackBox and that is the one I can recommend.

Debug Notices with GD Press Tools Pro

Debug Notices with GD Press Tools Pro

But, there is another plugin that can do much, much more to help you with debugging needs. And that is Dev4Press own: GD Press Tools Pro. When debugger is active, with the same errors as on the image with notices above, those errors will be part of debugger window, while the page content will be undisturbed. As you can see, plugin debugger is activated through red bug in the top of the screen (can be repositioned). It can have many tabs with all sorts of data. All notices, warnings and errors will be in this tab,and you can review it from there, no more mess in the page content.

Also, it allows expanding with new tabs, and other plugins or themes can add own data to it. Plugin adds few more debug tools: unserializer for JSON and PHP, fancy print replacement for displaying complex structures and tracker that profiles loading and can be used as a console to display data at any point in the code execution.

Conclusion

WP Debug mode is powerful tool to use, but it’s also not something everyone will be able to use effectively. When your site breaks, you will need debug mode as a first step in determining the problem, and if possible fixing it. At the very least info you get from it, will be useful to developers of the theme or plugin that are causing problems.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/wordpress-debug-mode-benefits-and-pitfalls/feed/ 0
Increase PHP Memory Limit http://www.dev4press.com/2011/tutorials/wordpress/practical/increase-php-memory-limit/ http://www.dev4press.com/2011/tutorials/wordpress/practical/increase-php-memory-limit/#comments Sat, 23 Jul 2011 22:10:39 +0000 MillaN http://www.dev4press.com/?p=6208 Anyone working with WordPress (or any other PHP based system) had a chance to see one of the most common fatal errors PHP has to offer: Allowed memory exhausted. This is easy to fix, and depending on your host and personal preference, there are several methods to do it.

Older WordPress versions (before 2.9) could work with 16M of PHP memory. Even later 3.x versions can work with so little memory if you don’t use any plugins. But, using plugins increases memory requirements, and using only 32M is at most times not enough. For latest WordPress with average of 20 plugins you will need 48M to 64M. Most hosting companies keep this value at 32M, so when you upgrade WordPress, upgrade plugin or add new plugins, you will run out of memory and you will see variation of this error (on screen or in log, depending on server settings):

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 345234 bytes) in /path/to/public_html/wp-content/plugins/plugin.php on line 56.

To increase memory, you can uses different methods. Examples bellow are for 64MB of memory. You can set it lower and experiment with higher values. Setting this to 128M or 256M is fine also, PHP will really use as needed, this value is limit. Use only one of these methods, don’t use all of them in the same time!

Method 1: Change PHP.ini

On some shared hosting servers and on VPS or other dedicated hostings, you will have access to php.ini file with all main PHP settings. This file should have memory directive, so you need to find it and change it, if it is not there, you need to add it. Here is the directive you need to find/add and set different value for memory size:

memory_limit = 64M

Method 2: Use .htaccess

If you don’t have access to php.ini, same thing can be done using .htaccess file. This file is in the root folder of your website, if it’s not there you can add it, but in most cases it is added by WordPress. This file is only available on Apache servers. Again, search for this in that file, if it is not there add it, and set memory value you need:

php_value memory_limit 64M

Method 3: Use WordPress wp-config.php

WordPress way to do this is using almighty wp-config.php file. If this define is in the file, change it to memory value you want, if it’s not there add it before “That’s all, stop editing!” comment in that file. Here is the code to find and change or add if not there.

define('WP_MEMORY_LIMIT', '64M');

Method 4:  Contact your hosting company

If you don’t want to do it on your own, you can always contact your hosting company support. Some hosting companies can impose limit to this value, so no method you can try can change it, and only hosting support can change it for you.

GD Press Tools: PHP Status

GD Press Tools: PHP Status

Check current memory limit and memory usage

Simplest way is to use our GD Press Tools plugin (you can see this with both Lite or Pro version). On GD Press Tools main page you can see the PHP Status block, and there you can find Memory Limit item and value for it. How much memory is used, plugin can add into the footer, and image bellow shows you used memory during the page creation, footer value is most important, that is total memory used for the whole page.

GD Press Tools: Memory usage

GD Press Tools: Memory usage

Admin side uses about twice as much memory then front end side.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/increase-php-memory-limit/feed/ 5
bbPress 2.0 Plugin: Basic Setup http://www.dev4press.com/2011/tutorials/wordpress/bbpress/bbpress-2-0-plugin-basic-setup/ http://www.dev4press.com/2011/tutorials/wordpress/bbpress/bbpress-2-0-plugin-basic-setup/#comments Mon, 13 Jun 2011 11:00:54 +0000 MillaN http://www.dev4press.com/?p=5707 bbPress 2.0 is a plugin for implementing forum into WordPress website. Its based on the old bbPress standalone web application made to integrate with WordPress. This time, plugin version is part of the WordPress and its using post types and taxonomies to store all data.

Plugin is relatively easy to install and setup, and this video shows the whole process from installing plugin, explaining forums, topics and replies, creation of static pages based on templates, bbPress compatible (and not so compatible) themes and basic info about using xScape themes with bbPress 2.0 plugin.

xScape Theme Framework has built in support for bbPress with templates based on the original templates in bbPress default theme, and because of that it will make easy switching to xScape powered themes without loosing previously created functionality. To read
more about plugin and xScape themes visit links bellow:

xScape theme Framework:
http://www.dev4press.com/themes/xscape/
bbPress Home:
http://bbpress.org/

]]>
http://www.dev4press.com/2011/tutorials/wordpress/bbpress/bbpress-2-0-plugin-basic-setup/feed/ 4
Improve your WordPress website speed, Part 2. http://www.dev4press.com/2011/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-2/ http://www.dev4press.com/2011/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-2/#comments Wed, 09 Mar 2011 12:00:57 +0000 MillaN http://www.dev4press.com/?p=4796 No matter how your website may be fast, it’s always good idea to find some new ways to speed it up. This time, speed will be gain by using very simple cache method that will allow you to cache some parts of the page: menus, widgets and other elements that don’t change that often.

Intro

Many parts of the page don’t change often, but require many SQL queries to be executed. If you have complex menu that combines categories, pages or posts and it can take more than 20 or even 50 SQL queries to make. For instance, all 3 menus on Dev4Press take about 30 SQL queries to get URL’s or structure. Similar situation is with widgets that don’t change every day, but can take a lot of SQL queries.

Cache method that I want to describe uses database to manually store rendered HTML into the wp_options table using transient records that can have expiry time, allowing you to set how long the cached data will be valid. In multisite mode, for rendering that is related to all websites you can use wp_sitemeta table with transient records. I will note the different functions for this later.

Cache Functions

We need 2 functions, one to store and other to get data from cache. You can store: objects, arrays, rendered HTML, anything really.

function dev4press_get_cached_data($name) {
  return get_transient($name);
}
function dev4press_set_cached_data($name, $value, $ttl = 43200) {
 set_transient($name, $value, $ttl);
}
  • $name: name for cached object, this needs to be max 45 characters in length due to the limit of database table structure.
  • $value: object/array/string to store.
  • $ttl: time-to-live, how long the cached value will be valid, in seconds

$name must be unique for the element you are storing. After the $ttl time expires, stored element will be invalidated. Also, functions up there are very basic, but they allow you to expand with calculating stats about the hits or misses, or whatever you might need.

Best way to use this cache is for caching complex operations that require more than couple of SQL queries or uses one or more very complex SQL queries. Transient cache requires 2 simple SELECT queries that are very fast. You can always measure operations to determine if the cache will give you performance boost or not.

Example: WP Menu Cache

Here is the example how to use this cache method for WordPress menu. WP theme to display menu is wp_nav_menu(). So, if you have menu named “my_menu”, it’s usually added to theme like this:

wp_nav_menu(array("menu" => "my_menu"));

To use cache, code will change to this:

$menu = dev4press_get_cached_data("cached_my_menu");
if ($menu === false) {
  $menu = wp_nav_menu(array("echo" => false,"menu" => "my_menu"));
  dev4press_set_cached_data("cached_my_menu", $menu, 86400);
}
echo $menu;

Line 1 attempts to get stored menu from transient cache by key “cached_my_menu”. If the result is false, than we build the menu as before (using echo parameter set to false, so that menu is not displayed) on line 3. And when the menu is built, we need to store rendered HTML to transient cache using same ”cached_my_menu” key on line 4. And than display menu on last line.

First time the menu needs to be displayed, cache will be empty, and lines 3 and 4 will execute making menu and caching it. Next time, line 1 will get the menu from cache skipping rebuild part. After 24 hours (86400), menu will be invalidated, and first line will again return false, and menu will be rebuilt again.

Same principle can be used to handle any type of data to cache.

gdr2 Library

My gdr2 Library used in all my premium plugins and themes has own Cache class that is based on this method. Cache class supports statistics, unique name building and other things. It’s used to cache widgets in plugins and to cache widgets and menus in xScape themes. On Dev4Press website, powered by lightScape theme, widgets are cached and also main menu and the footer links map. Top menu items depend on the user, so it’s not the same for everyone, and caching it is not good idea.

Conclusion

I will search further for more things you can do to optimize websites, so more posts like this will be added. If you have some more suggestions on WordPress speed improving, please leave a comment.

]]>
http://www.dev4press.com/2011/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-2/feed/ 2
Ultimate Guide to WordPress Security http://www.dev4press.com/2010/tutorials/wordpress/practical/ultimate-guide-to-wordpress-security/ http://www.dev4press.com/2010/tutorials/wordpress/practical/ultimate-guide-to-wordpress-security/#comments Thu, 30 Dec 2010 13:00:19 +0000 MillaN http://www.dev4press.com/?p=4406 Over the past 2 weeks I have published 6 articles/tutorials on different security aspects related to WordPress, covering everything from server environment, file system using of .htacess file, WordPress tips, methods for spam prevention and recommendations for improving plugins and themes security.

So far released security articles are linked bellow. I tried to cover as much topics as I could, and I am sure that some things are still not included. But, I use on my websites things I wrote about, and I am very satisfied with the results. If you have some suggestions or some other tips and tricks that are security related, suggestions about the plugins you used, please leave a comment.

Part 1:
Hosting Environment
Part 2:
Files Protection
Part 3:
HTAccess Tips
Part 4:
Inside WordPress
Part 5:
Spam Prevention
Part 6:
Plugins & Themes

List is not final, and as needed I will add more. There will be at least one more .htaccess article with focus on using that file to protect wp-admin folder, one article with advises to developers on making their plugins more secure and if you have more suggestions, or you need more answers to security related questions, leave a comment and tell me what should I write about in the future when the WordPress security is concerned.

Also, I would like you to share your experiences with anything security related, as I am sure that will help other WordPress users to better prepare themselves and better protect their servers and websites.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/ultimate-guide-to-wordpress-security/feed/ 0
WordPress Security, Part 6: Plugins & Themes http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-6-plugins-themes/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-6-plugins-themes/#comments Wed, 29 Dec 2010 13:00:00 +0000 MillaN http://www.dev4press.com/?p=4206 WordPress website can’t work without plugins or themes. Well, you don’t need plugins, but in most cases WordPress alone is not enough. Choosing, downloading and using both themes and plugins may look as a simple task, but with increased popularity of WordPress it’s not anymore.

Millions of websites run on WordPress, and that makes WordPress and everything related to it great target for hackers to exploit security holes and to plant some of their own into plugins and themes. Every now and them you hear that some plugin is used by hackers to get access to websites or to send users data to a remote website. Similar methods are used by themes. Themes are also used to plant spam links into header and footer of websites using encoded content (base64 or some other method). Some themes also had a malicious code that was able to replicate itself to other themes installed on the website.

Preventing something like that happening to you is not very complicated, and it requires that you only be careful where you get the plugins and themes, and what are you installing on your website.

Find and download themes and plugins

Best source for free themes and plugins is main WordPress website (wordpress.org). Themes uploaded there are always scanned prior to publishing to make sure that malicious code is not embedded. When the plugins in the repository are concerned, it’s not nowhere near as strict as the themes, and plugins are removed only if multiple users report plugin as problematic. Over the years, there were cases of plugins uploaded to repository that where malicious in nature, but they are always quickly removed. Still, plugins repository needs a massive overhaul to make it up to date (90% of plugins are not compatible with latest WordPress versions, they are not maintained and they are not tested). But, as a source of free plugins that is the best way to get plugins.

If you don’t download plugins or themes from there, you must make sure to get plugins and themes directly from their authors websites. Be careful downloading them from some third-party website. Free plugins are not big problem, but premium (or commercial if you like) plugins and themes are usually target of hackers. They get them illegally, change them and offer for free from their websites or other warez forums or sources. All commercial themes developers were affected over the years, and their themes end up on such websites, and always include some sort of malicious code.

Check what you have downloaded

Before you upload theme or plugin on your website, test it on your local computer. Also, you can search files in theme or plugin for a code that is potentially problematic. This is easier to do in the theme than plugin, since plugin can have not only more files, but there are legitimate reasons to use some functions that may be considered problematic.

Any theme file can be affected, but most common files to be infected are: functions.php, footer.php and header.php. Encoded content is usually recognized by use of base64_decode function that contains long string that doesn’t make any sense on its own. Also, footer or header can contain long lists of links that are displayed as hidden. There is a free plugin called Theme Authenticity Checker, and you can use it to scan themes you have installed to find malicious code or links that shouldn’t be there.

There are several ways that plugins and themes can send data to remote servers. That can also be a big security concern and check if curl functions are used, functions like wp_remote_get or file_get_contents. Checking for that requires that you are familiar with PHP and WordPress development.

Conclusion

Be careful what you add to your website, make sure to get plugins and themes from authors or some reputable source like official WordPress repository. Spend some time to test what you have download.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-6-plugins-themes/feed/ 0
Expanding Plugins Panel with Links and Info http://www.dev4press.com/2010/tutorials/wordpress/tips/expanding-plugins-panel-with-links-and-info/ http://www.dev4press.com/2010/tutorials/wordpress/tips/expanding-plugins-panel-with-links-and-info/#comments Tue, 28 Dec 2010 10:45:48 +0000 MillaN http://www.dev4press.com/?p=327 If you are plugin developer, it’s very important to give as much info about the plugin updates as you can before the blog admins update the plugin to a new version. Also, some of the plugin control panels go into different menus, and it’s a good idea to have direct links on the plugins panel also.

Examples bellow are for WordPress 2.9 or newer. This is re-revised version of last years tutorial, this time with added meta info links block. New method is used that doesn’t require for you to check if the filter is executed for your plugin only. New filters already include plugin name in the filter name.

Additional options

Each plugin row on the Plugins panel has several standard actions. You can add more actions like the link to the settings panel or anything else. You need to add filter function that will be used to add this action(s).

<?php
add_filter('plugin_action_links_$plugin_file', 'add_plugin_links');

function add_plugin_links($links) {
  $links[] = '<a href="index.php">Dashboard</a>';
  $links[] = '<a href="edit.php">Posts</a>';
  return $links;
}
?>

Lines 5 and 6 are adding new action to the plugin row. This example adds link to the dashboard and to post edit page, you can change it to whatever you need. Don’t forget to return $links because this is a filter not an action.

Very Important: On line 2 filter has $plugin_file. You need to replace this with the relative path/name of the main file of your plugin. For instance, my plugin GD Press Tools has a $plugin_name: gd-press-tools/gd-press-tools.php. It has folder name, slash, main plugin file name (with extension), and full filter name will be than: plugin_action_links_gd-press-tools/gd-press-tools.php. Same method will be used in the last expand examples.

Plugin Meta options

Description column in the plugins grid have also number of links. This can be expanded similar to additional options from previous block.

<?php
add_filter('plugin_row_meta', 'add_plugin_meta_links', 10, 2);

function add_plugin_meta_links($links, $file) {
  if ($file == "$plugin_name") {
    $links[] = '<a href="index.php">Dashboard</a>';
    $links[] = '<a href="edit.php">Posts</a>';
  }
  return $links;
}
?>

Lines 5 is there to ensure that you add settings only to your own plugin. Lines 6 and 7 are actually adding new action to the plugin row. This example adds same links as previous one, but, you can add whatever you want leading to your own plugin. In the case of this filter, you must check on your own if the filter is run for your plugin.You must $plugin_name on line 5 with the string as described in the first example above.

Additional plugin info

WordPress shows description from your plugin file. And when the new version is available for update, there is no detailed info about the the update. Adding that is not very hard.

<?php
add_action('after_plugin_row_$plugin_file', 'add_after_plugin_meta');

function add_after_plugin_meta($file) {
  $current = get_site_transient('update_plugins');
  if (!isset($current->response[$file])) return false;

  $url = "http://www.yoursite.com/info.txt";
  $update = wp_remote_fopen($url);
  echo '<tr><td colspan="3">'.$update.'</td></tr>';
}
?>

Function checks to see if you add row to your plugin as the previous function does. Lines 5 and 6 will check if there is an updated found for your plugin. If no update is found, additional row will not be added. You can remove this part, and added row will be always visible. My intention with this code is to display details about the plugin update, you can change it to anything else. You need to echo only TD part of the row, WordPress already echoes TR tag. Function will get contents of the file from $url variable and will echo that file in the row.

Example

Example

Example above shows both functions used in GD Press Tools plugin. First row is a standard plugin info, and you can see Settings action added by first function. Second row is WordPress info that plugin upgrade is available. Third row is info displayed by second function that has retrieved this changes notice from my website.

This example uses same $plugin_name method that is described in the first example.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/tips/expanding-plugins-panel-with-links-and-info/feed/ 8
WordPress Security, Part 5: Spam Prevention http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-5-spam-prevention/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-5-spam-prevention/#comments Mon, 27 Dec 2010 13:00:55 +0000 MillaN http://www.dev4press.com/?p=4189 Most annoying thing when running a WordPress based website is cleaning up spam comments (there is no sure why to fully eliminate it) and removing spam blogs if you run open multisite installation of WordPress. Some of the things to help with this were already part of previous articles.

If you run open blog that allows user registration and allow comments from register users only, great deal of registered users will be spam source. Eliminating such users is a big problem. Even bigger issue is multi site WordPress installation where registered users can get own blogs that can than be used as a source of spam. Filtering all that manually is very slow and tedious process. For spam comments you can use Akismet plugin and some .htaccess tricks. For spam registrations, problem is much bigger and as far as I know GD Press Tools Pro is the only plugin that can help you with that.

Akismet

Best system for automatic spam comments detection and filtering is Akismet. Plugin comes built-in with every WordPress installation, and it is very easy to use and it’s usually very precise eliminating spam comments. But, it’s not perfect, especially if you run popular website that get a lot of comments each day. Here, on Dev4Press, Akismet removes some 7.000 spam comments each month, missing couple of comments each day (on average). This is really good result, and requires only minor involvement on your part. Still, I would recommend that you check comments marked as spam at least while you are sure that Akismet filter is precise and is not removing comments you might want.

.htacess File

As mentioned in third security article, .htaccess can be used to prevent sending great deal of spam comments based on referer and user agent.

GD Press Tools Pro: Registration Filtering

GD Press Tools Pro: Registration Filtering

Use GD Press Tools Pro to eliminate spam registrations

GD Press Tools Pro monitors all user registrations attempts and can use 9 different methods to check if the registration is valid (see image on the right). If any of the methods fail, registration will be prevented. And also, system can learn and improve filtering by using previously logged data.

Plugin will check email, username, domain part from the email and user agent from the request. Many spam registrations use invalid user agent that reveals that request is not coming from human user using browser. If any of the filtering method is triggered, it can be used to automatically ban username used, email, domain or IP. This data, if logged, it can be used further.

Plugin also has Registration panel where you can see this log, and what is banned, allowing you to manually ban or remove existing ban further improving filtering. Using this feature on several websites, I managed to prevent more than 80% of spam users registrations. With proper control of logged data, this can improve further.

Preventing spam registrations in multisite environment is very important, since spam blogs will generate content that is against the rules and topics you might allow, can cause problems with search engines, and will generate an enormous amount of warez and links and pirated content you don’t want in your network. Checking each site manually is very long and complicated process, that with GD Press Tools Pro Spam Registration prevention can be significantly faster because plugin will eliminate most of such users.

Other plugins

There are many so-called Antivirus plugins that are totally useless since they add one or two features that are hard to control and tweak, and I already have that in GD Press Tools Pro. You can count on getting more security tools to this plugin to minimize the need of having many different plugins that don’t actually do much in terms of security and administration of your WordPress websites. In the past several months I have tried all security and antivirus and other similar plugins from WP repository and I can’t recommend any of them if you want to prevent spam on your blog.

Conclusion

Spam prevention is very important problem, that only gets bigger when website gains in popularity and increased number of visitors and users. There are very few plugins available for this, and maybe handful is actually useful. I only focused on Aksimet and my GD Press Tools, since that are only two plugins that actually made important difference in my everyday work and maintenance of websites.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-5-spam-prevention/feed/ 0
WordPress Security, Part 4: Inside WordPress http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-4-inside-wordpress/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-4-inside-wordpress/#comments Wed, 22 Dec 2010 13:00:52 +0000 MillaN http://www.dev4press.com/?p=4191 After you have secured your server file system and set the .htacess file, you can now turn to WordPress and make some changes or add features that will help improve security even further. And some of the tweaks proposed in this article are very important against several types of attacks.

Username: admin should be changed

Before WP 3.0, in every new installation of WordPress, main user account was named admin. After WP 3.0 you can choose new username during installation. Also, WP doesn’t allow changes of username directly. It’s not recommended to have admin username at all because hackers expect it and can use it to only crack the password and get access to your website. Considering that many websites use simple passwords, that can be easier than you may think.

Update WordPress, plugins and themes

This is something you hear from everyone: keep your installation up to date. But, on the other hand that can be a problem in some cases. Updating WordPress is a good thing if you don’t use some old and outdated plugins that don’t work with new WordPress, and is not maintained anymore. Situation with updating themes is similar, once you start changing the theme, you can’t update anymore or you will loose your changes. That is one of the reasons I added theme upgrade to my xScape premium themes, allowing you to change theme and still be able to update with new version.

If you still run some old WP version (any 2.x version), from security point of view, you need to upgrade to latest WP 3.x version. If some old plugin is preventing you to do that, try to find someone to fix the plugin or write a new one. Investing in that can prove very important to keep your website safe in the long run.

Best security policy with WordPress (and other well maintained CMS systems) is to use latest versions, since WP core developers are always been very fast in fixing all potential security holes. Compared with other similar systems, in my experience, WordPress is most secure one with a lot of security features built into the core.

Remove WordPress version

Each WP page contains meta tag with version of WP. It’s best to remove it so that hackers can’t use that info to target your website with potentially targeted attacks, and that is potential problem with older WP versions. To remove the WP version, you can use this line:

add_filter('the_generator', create_function('$wpv', "return null;"));

Injection attacks through URL

One of the most common attacks hackers use is adding so called injection code to the URL. If the URL is not properly filtered, such code can take advantage of bugs in the WordPress (or other CMS systems), and run SQL query that can be very harmful. WordPress already does good job in preventing such attacks, but it is a good idea to detect such attacks and log them so you can use that to prevent access to such users in the future. Scanning and filtering URL can be used to prevent too long URL’s also.

There are many variations to this code allowing filtering on admin side only, or for some user roles. But, core code is this:

$url = $_SERVER['REQUEST_URI'];
$request_url = $_SERVER['REQUEST_URI'];
if (stripos($request_url, "eval(") || stripos($request_url, "CONCAT") || stripos($request_url, "UNION+SELECT") || stripos($request_url, "base64")) {
  @header("HTTP/1.1 414 Request-URI Too Long");
  @header("Status: 414 Request-URI Too Long");
  @header("Connection: Close");
  @exit;
}
GD Press Tools Pro: General Security Settings

GD Press Tools Pro: General Security Settings

Using GD Press Tools Pro

GD Press Tools Pro allows you to do all the things listed in this article, and a lot more minor tweaks and changes. Some things are global security settings or available for individual sites (if you run multisite installation). Image on the right shows one more feature that can be useful to force settings CHMOD for files and folders created by WordPress for some hosting systems where default CHMOD’s are not already properly set.

Conclusion

Keeping WordPress website safe mostly depends on outside factors we discussed in the previous parts of WordPress Security articles series. But, there are still some minor things that can help if you make some changes from inside WordPress.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-4-inside-wordpress/feed/ 0
WordPress Security, Part 3: HTAccess Tips http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-3-htaccess-tips/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-3-htaccess-tips/#comments Mon, 20 Dec 2010 13:00:08 +0000 MillaN http://www.dev4press.com/?p=4187 .htaccess is directory level configuration file used by Apache (and some others) web servers. Content for this file is very similar to web server global configuration file. Htaccess is used to override settings from global configuration and can be added to any directory of the website.

I will not bore you with everything .htaccess can be used for, because it’s a lot, but here are some basics. WordPress uses .htaccess for activating rewriting engine and getting all the pretty permalinks that we are so used to. So, most likely you will have .htaccess file in the root of your website installation. You can add .htaccess to any directory, if you need to set something differently from parent directory, a good method to add extra protection to wp-admin folder.

Based on some server settings .htaccess maybe hidden from FTP access. All the code examples explained below can be added anywhere in the .htaccess. Always add comment lines, (starting with #) so you can find out what piece of .htaccess is doing what. If the website gives internal server error message after you change .htaccess, than you made a mistake in the syntax, so it’s a good idea to make a backup of the file before you start editing.

File Protection

Basic thing you can do with .htaccess is to protect files from being accessed at all. Some types of files are already protected by global server configuration, but it’s better to ensure the protection using .htaccess also. You should protect .htaccess and wp-config.php files at least. If you attempt to access wp-config.php like this: http://www.example.com/wp-config.php, you will get empty page, since PHP is processing and that file and has no output to display. But, due to some exploit methods that can affect server, it’s also good idea to prevent access to this file. It’s recommended to prevent access to readme.html, since it contains WP version.

# deny access to wp-config.php
<files wp-config.php>
order allow,deny
deny from all
</files>
# deny access to readme.html
<files readme.html>
order allow,deny
deny from all
</files>
# deny access to .htaccess
<files .htaccess>
order allow,deny
deny from all
</files>

With this method you con protect files located in the same directory as .htaccess. To do the same with files in some other directory, you need to create .htaccess in that directory also.

Prevent Directory Browsing

By default, web server allows browsing of directories on the website, and that can reveal the content of directories that are not protected. One way to prevent that is to add index.php or index.html file to each directory, but better method is to do it with .htaccess and prevent it for all directories at once.

# prevent folder browsing
Options All -Indexes

Limit website access based on user agent

Each web request should contain the user agent string identifying source of the request. UA strings are used to identify different browsers or other programs trying to access website. Based on the UA string we can identify many spammers, content scraper and other source that it’s best to ban from the website. With that you can even improve website performance since requests from banned sources will be stopped before server will generate content. There are many good lists available on the internet, and one such list is part of GD Press Tools Pro plugin (more info at the end of the article).

# deny website access based on user agent
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} almaden [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xenu [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus.*Webster [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]

This is only partial list just to show how the list is made. You can add more lines and more user agents to ban. You can use full user agent string, or part with use of regular expressions.

Deny comment posting to requests with no referer

Akismet is a great plugin to eliminate comment spam, but there is a way to help it a bit with a simple addition to .htaccess. Following code will prevent posting comments to requests that have invalid referer. Each request contains referring URL that points the source of request. If referer is missing, than request is a direct one, and in case of comments that can’t happen, since referer should be comments form page. No referer, equals spam.

# prevent comment posting to requests with no referer
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.*example.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]

Replace example.com with your own domain name.

Limit request body size

PHP and Apache have settings to limit upload file size. But, request size is still not limited, and in some cases large body size of the request is used in DDoS attacks. So, you can limit the size of individual request using .htaccess. This will also limit the upload size, so don’t set it to low if you need large files uploaded. Size is given in bytes, and in example bellow it’s about 10MB.

# limit size of request body
LimitRequestBody 10240000

Banning website access to some IP’s

If you want to ban one or more IP’s to access your website, you can do it by adding new rules to .htaccess. You can add full IP, or partial IP that will cause all IP’s in the range to be banned. Here is the example code:

# ban access to some IP's
<Limit GET POST>
order allow,deny
deny from 200.49.176.139
deny from 99.88.77.*
deny from 99.*.*.*
deny from 98.81
deny from 99.88 99.88.77 11.22.33
deny from domain.com
allow from all
</Limit>

Line 4 is one full IP. You can add more IP’s in a single line separated by space. Lines 5, 6 and 7 are partial IP’s that will ban a whole range of matched IP’s. Line 8 is example of several partial IP’s in a single line. Also, you can ban domain names like on the line 9.

Use GD Press Tools Pro for easy update to .htaccess

GD Press Tools 3.9 Pro: HTaccess

GD Press Tools 3.9 Pro: HTaccess

GD Press Tools 3.9 Pro adds a .htaccess modifications to Security panel. Right now this panel allows you to control all tips from this article (except for IP limitations, that will be added in 4.0). Plugin can modify and update .htaccess on its own, so you don’t need to do it manually ever time you need to change something, just enable or disable some of the options, and plugin will do the rest.

IP banning with .htaccess will be added in GD Press Tools 4.0 Pro and will be part of the spam and registration prevention plugin already has. Check out other security related features built into GD Press Tools 4.0 Pro.

Conclusion

There are more things that can be done with .htaccess when the security is concerned. I think that this is enough, some other more obscured tips can be overkill and they will not improve security further. But, if you want more, I will write one more article with more complex .htaccess elements. One of the most complex is use of .htpasswd files for server-based authentication.

Resources

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-3-htaccess-tips/feed/ 2
WordPress Security, Part 2: Files Protection http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-2-files-protection/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-2-files-protection/#comments Thu, 16 Dec 2010 13:00:21 +0000 MillaN http://www.dev4press.com/?p=4214 First step to ensure that your WordPress website is secure, is to set proper file permissions rights. Wrong file permissions can easily lead to hackers gaining access to your website. So, after you first install WordPress, no matter what method you used, you must check those rights and set them properly.

When you first install WordPress, you can do it manually or you can use some sort of install script that is usually offered by the shared hosting companies. In my experience, those scripts usually do a good job in setting at least initial file permissions to all files and folders. But, on the other hand that may not always be the case, and you can end up in problems.

Main issue is to allow WordPress to access files and folders it needs to be able to work properly, and in the same time not to set permissions too loose so that it can be exploited. To change the file permissions, Linux uses CHMOD command. Permissions for files and folders are represented by three values controlling access for file owner, for owner group and for everyone else (world). And each of these controls 3 rights: read, write and execute. There are different ways to display file permissions, and most common is to use 3 numbers: first for owner, second for group and third for world. File system and file permissions can be very complex, and more info on how all that is working can be found on URL’s at the bottom of this articles.

Since we are talking about file system on your server, referring to users and groups has nothing to do with WordPress. User or owner is your account on the server not in WordPress.

Recommended permissions

Before you check and set CHMOD for files and folders, it’s recommended that owner for all files and folder is your user account on the server. If, when you copy new files or add new files, this is not the case, and if server is setting someone else as an owner, then, there is something wrong with your server settings. In my experience, this usually happens if you are installing and setting server on your own (VPS hosting) and you missed configuring file system ownership, that depending on OS you use, can be set to Apache process or something else. Make sure that all files and folders in your WP installation are owned by your user. All other recommendations are based on this one, so make sure it’s set as it should be.

FTP View of Permissions

FTP View of Permissions

For all folder in the WordPress installation, recommended permission is 755. This means that owner (first number, 7) can read, write folder and execute content in it. Group and world can’t write. This makes folders safe from anyone beside your main user adding new files, or deleting existing files. Files should be set to 644, the same as 755, but with no execute set. For folders you need owner, group and world to be able to at least read from the folders, or your website will not be publicly accessible, so that’s why 5 is set for group and world.

If you are using FTP or command line tools, you will usually see permissions displayed like on the image on the right with string with 10 characters. First is telling if it’s file or folder, and 9 are flags for all 3 groups, 3 rights each. Here you can also see owner and group. While they are named, here are codes representing the names on your server.

Specific files permissions

For some files and folders you can use different permissions to make sure that they are extra secure. So, for wp-config.php, recommended permissions is 640 or even 600. Same goes for .htaccess files. In shared environments, you can also have PHP files present (php.ini and/or php.cgi). For these files you can set even more restrictive permissions: 100, and only owner can execute these files, nothing else.

File Permissions in GD Press Tools Pro

File Permissions in GD Press Tools Pro

GD Press Tools Pro

To do all this, you can use command line on your server, FTP access or file manager you have in the control panel for your hosting account. But, you can do it from WordPress also. GD Press Tools Pro on the Security panel shows most important files and folders in your WP installation, their files permissions and options to change those that are not restrictive as recommended values are.

Also, on the Security panel, tab General you can set default CHMOD values WordPress can use to set on newly created files and folders (uploads mostly).

Conclusion

Permissions described in this article will be enough to make all critical areas of your website secure. But, you can take this further and experiment with more restrictive rules for some folders, or some more files.

Resources

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-2-files-protection/feed/ 0
WordPress Security, Part 1: Hosting Environment http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-1-hosting-environment/ http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-1-hosting-environment/#comments Tue, 14 Dec 2010 13:00:18 +0000 MillaN http://www.dev4press.com/?p=4185 First thing you need to take into consideration when security of the website is concerned is the server you host your website on. There are 3 main hosting type environments and depending on what you are using there are different security related concerns you must take into account.

Hosting companies are offering UNIX/Linux-based servers or Windows-based servers. Due to pricing of Windows licenses, they are not commonly used to host websites based on WordPress or other PHP based systems. Most servers will run on different distributions of Linux, and they commonly use Apache as web server. I will not write about Windows-based servers, since they are much different to set up and use, and also they are very rare for WordPress website, and not really relevant for this article.

Shared Hosting

Most websites, especially smaller websites are hosted on the shared hosting servers because they are cheap and they are powerful enough to run. Shared hosting means that a single server is used for many different users accounts. Server is not yours to use and modify as you need, you are limited by the shared environment settings that hosting company set for all accounts on a server. There are some things you can change and use.

If you decide to choose shared hosting company, make sure that they are using latest (or at least current) software: Apache server (or something similar), PHP (version 5 is a must, with 5.2 or 5.3 being preferable) and MySQL (version 5 is most commonly used). They need to allow you to use HTaccess files (there are still many hosting companies that don’t) and preferably allow you to use own copy of PHP.INI file for some settings that can be changed for each account. Good support is always important, especially until you set everything and make sure that server is working right. Always require access to some sort of control panel: CPanel, ISPManager or Plesk (there are others, these are the best).

Shared hosting is limited in what you can do with the server (again, it all depends on the hosting company), and you will not be able to install additional software: Firewall, PHP extensions, MemCache… Most shared hosting companies have decent security related setup, but again, make sure to check what are you getting into.

Sharing server by default means that all accounts and all domains on it will share single IP address. So, if that IP gets blacklisted for some reason because of some other user, you will be affected also. Most shared hosting companies offer purchase of separate IP for your account only.

Virtual Private Servers Hosting

Or VPS for short is becoming very popular in the recent years, mostly due to much better performance you get and much affordable prices caused by many more emerging companies offering this kind of service. VPS is basically a whole server only for one user, this server is not actual physical machine, but a virtual machine-made through process of virtualization and sharing of hardware resources. There are many different methods for this used today with nodes distribution and clouds getting more in popularity. You are only user of your VPS, and you can have full control over installing the server and setting it up. VPS can be unmanaged (you need to do everything by yourself), or is managed where hosting company is still in control of installing the server and helping you run it.

If you decide on VPS hosting, be prepared to work more on the server setup and maintenance (depends on managed or unmanaged VPS configuration). If you need to use mail server on your VPS (and in most cases you will need that), make sure to set mail server properly: reverse DNS (usually you need to ask for this from the hosting company), set up limits, SPF records… Be sure to run latest version of OS you have decided on, updated kernel, updated web server, PHP and mySQL. Also, I strongly recommend installing some firewall software (LFD is really good one with a lot of options to set). Make sure to use strong passwords for everything and to change them often. If you run personal server (no outside users), there is a less chance of intrusion because you will be only one that has access to it.

PHP also can be improved and expanded to include Suhosin security extension. Some Linux distribution (like Ubuntu 10.04), will install PHP with built-in Suhosin. To be honest, I don’t like it and I don’t use it. I find it hard to set up, and it was always causing more problems than I was prepared to deal with. But, if you have patience and time to test it, I recommend trying it. As for the mySQL, usually server is set to allow only local access to it, so no one can access it from outside your server.

VPS is the best solution for hosting: not very expensive, full control over the server, great potential for setting it up exactly as you need and in most cases very easy to expand to use more hardware resources when your website(s) starts to grow and to get more visitors.

Dedicated Hosting

What I said about VPS can be said for dedicated hosting. But, in this case you actually have use of full physical machine. This is usually very expensive solution, but most powerful one. If you don’t care about spending more money, this is the best solution and the most complex from maintenance standpoint and work you need to invest also..

Useful Resources

Here are some online tools and resources that can help you with the server and hosting environment.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/wordpress-security-part-1-hosting-environment/feed/ 0
Custom posts filtering with taxonomy terms http://www.dev4press.com/2010/tutorials/wordpress/practical/custom-posts-filtering-with-taxonomy-terms/ http://www.dev4press.com/2010/tutorials/wordpress/practical/custom-posts-filtering-with-taxonomy-terms/#comments Wed, 17 Nov 2010 23:01:34 +0000 MillaN http://www.dev4press.com/?p=3716 Only when you get to work on a really huge WordPress website with hundred thousands of posts, post tags and other elements, you will realize that many operations you think as common are going to get very, very slow even on very powerful servers. What to do than?

Intro

In some cases, it’s best to give on WordPress and make your own CMS that is made for the need you have. Getting some other CMS is most likely not good solution since it will have some other issue that will cause troubles, since all CMS have one fatal problem: they are not made for a single purpose, they are made to cover all sorts of uses, and this type of generalization will always be slower than custom use specific coding. But, I don’t plan just to give up on WordPress for such complex tasks, best is to make changes that will solve the problem.

Main problem and major slowdown on the AppHelp website was getting list of posts belonging to a post tag. One run of the query can take up to 1 minute (yes, one whole minute), and that’s not good. Using cache plugin is partial solution, and I prefer to have something that will solve the issue at the source, not to patch it after.

Solution(s)

Solution to this problem is to change the SQL query WP generates to get posts archive based on tags. The solution I have in mind takes 2 queries instead of 1, and these 2 queries need only 0.2 seconds to run. Compare that to 30 seconds (on average) original query takes for such large database, and you will see that new method is 100 times faster! Minor downside is that mySQL for these 2 queries will use a bit more memory (I managed to measure some 15% increase), and in my book that is a fair trade off for the massive speed improvement we got.

Original WP code gets post tag (term) slug and makes a query that joins posts table with all 3 taxonomies tables. If you want to use multiple terms SQL where clause will try all of them in the same time, and in all cases will search by VARCHAR field. So, there are actually two solutions. First, and simpler one is to use term ID’s in where, instead of slug names. This is actually method WP uses to filter categories and category pages are much faster than post tags because of simple SQL. But, that method is still slow, as it takes up to 10 seconds to run, and we want to get it much, much faster.

My solution is to add one more step. First, get the term ID’s for all terms. Than, make a new SQL query that will join posts table directly to the secondary, nested SQL query that will use term ID’s. Such method is very, very fast.

The Code

So, how to actually do this? Since we need to change whole query not only parts of it, there is only one way to do it without actually hacking WP_Query class. We need to hook up after the query is created and than make our own query. To do that we need to add filter for ‘posts_request’. This will give as full query made by WP_Query object, and the current instance of WP_Query object. Since, only problem are taxonomy pages (mostly tags in my case) code will check out if we are on the right page.

<?php
add_filter('posts_request', 'dev4press_posts_request', 10, 2);

function dev4press_posts_request($sql, $wpq) {
  if (is_tag() || is_category()) {
    global $wpdb;

  if (is_tag()) {
    $tax = "post_tag";
    $t = get_term_by("slug", $wpq->query["tag"], $tax);
    $terms[] = $t->term_id;
  }
  if (is_category()) {
    $tax = "category";
    $t = get_category_by_path($wpq->query["category_name"], false);
    $terms[] = $t->term_id;
    $terms = array_merge($terms, get_term_children($t->term_id, 'category'));
  }

  $sql = sprintf("SELECT SQL_CALC_FOUND_ROWS %s.* FROM %s INNER JOIN (SELECT DISTINCT tr.object_id as ID FROM %s tr INNER JOIN %s tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.taxonomy = '%s' AND tt.term_id in (%s)) t ON %s.ID = t.ID WHERE %s.post_type = 'post' AND %s.post_status = 'publish' ORDER BY %s.post_date DESC LIMIT 0, 10", $wpdb->posts, $wpdb->posts, $wpdb->term_relationships, $wpdb->term_taxonomy, $tax, join(", ", $terms), $wpdb->posts, $wpdb->posts, $wpdb->posts, $wpdb->posts);
  }
  return $sql;
}
?>

This code can be changed for different purposes, this is just an example on how to make this work. Feel free to experiment. You can use $wpq (WP_Query instance) to get preset parameters and with that modify query further.

Speed improvements

First case is one category and all subcategories. Original SQL query took 21 second, modified query took about 1.5 seconds. Query for a single category is second case. Original SQL query took 1 second, modified query took about 0.2 seconds. This is the smallest gain, but everything counts. Last case is the filter by post tag. Original SQL query took 66 seconds, modified query took about 1.2 seconds. And that’s where this query method knocks out WP out of the park.

Conclusion

There are many cases where WP core will be slow and the only solution is to rewrite parts of it. In most cases use of filters will be enough to make changes, but there are some elements where only direct hacking of WP core is the solution. I will try to avoid such things as much as I can. Main WP development rule: don’t change the core files.

This is not something that you will need for every website, but it’ a good idea to have this around if you are working on not so typical WP website where using core code can cause website to be slow. For small websites, such issues will never occur, but for bigger websites many things in WP core are slow.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/custom-posts-filtering-with-taxonomy-terms/feed/ 0
Adding large number of terms http://www.dev4press.com/2010/tutorials/wordpress/practical/adding-large-number-of-terms/ http://www.dev4press.com/2010/tutorials/wordpress/practical/adding-large-number-of-terms/#comments Tue, 26 Oct 2010 22:30:28 +0000 MillaN http://www.dev4press.com/?p=3565 Due to the nature of working with terms and taxonomies, WP core functions that are used to add new terms are quite robust, but in the same time very, very slow. This article will show how WP terms function work and what problems that can cause for large websites.

For normal usage, adding terms doesn’t affect WP working much, since you will publish post at a time. But, if you have some automatic publishing procedure that have to publish 100 or more posts at the same time, you have large number of posts, large number of tags and more than 2 default taxonomies, assigning terms can take quite a long time.

Massive website I am working right now on, has 300.000 posts, 40 categories and currently 100.000 tags (for some 30.000 posts only at the moment). To get tags for the rest 270.000 posts using current default WP function wp_set_post_terms() it will take about 2 weeks to complete on a very, very fast VPS server. And that is only adding normal post tags, if you need something like that with hierarchical taxonomy with same number of terms, this can take much longer. Why?

How WP adds and assigns terms?

If you use wp_set_post_terms() function, there are several things WP needs to do to ensure that terms added are not duplicates, that are not assigned already. In case of hierarchical taxonomies things are more complicated, because WP needs to check the whole hierarchy. To add new term WP can execute between 10 and 16 queries , and even 20 for hierarchical taxonomy. With large database these queries can take long time to execute. For the website I am working on now, typically one post gets 15 tags, and running all that can take even 4 seconds per post, and that is about 2 weeks needed to process! And, for what we need that is simply unacceptable.

How to solve this problem and speed process up?

Well, it all depends on what you need and what kind of flexibility you search for. For the project I am working now, I have written functions to replace default WP wp_set_post_terms() function. New functions are for post_tags only, and they are removing several steps that are not needed in the specific case we have here. New set of functions is some 6 times faster than default function and it takes 3 to 5 SQL queries per term. Also, new SQL queries are simpler and with that faster. But, they will work only with non hierarchical taxonomies and they will always work in append mode, adding terms to posts.

Here is the source code for functions needed, feel free to use them. Last function in the source is one you need to add terms to posts (or any other object).

<?php
function dev4press_insert_term($name, $taxonomy = 'post_tag') {
 global $wpdb;
 $args = array('name' => $term, 'taxonomy' => $taxonomy, 'alias_of' => '', 'description' => '', 'parent' => 0, 'term_group' => 0);
 $args = sanitize_term($args, $taxonomy, 'db');
 extract($args, EXTR_SKIP);

 $name = stripslashes($name);
 $slug = wp_unique_term_slug(sanitize_title($name), (object)$args);
 $wpdb->insert($wpdb->terms, compact('name', 'slug', 'term_group'));
 $term_id = (int)$wpdb->insert_id;

 $wpdb->insert($wpdb->term_taxonomy, compact('term_id', 'taxonomy', 'description', 'parent') + array('count' => 1));
 $tt_id = (int)$wpdb->insert_id;

 return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
}

function dev4press_term_exists($term, $taxonomy = 'post_tag') {
 global $wpdb;

 $sql = sprintf("select t.term_id, tt.term_taxonomy_id from %s tt inner join %s t on t.term_id = tt.term_id where t.name = '%s'", $wpdb->term_taxonomy, $wpdb->terms, $term);
 return $wpdb->get_row($sql, ARRAY_A);
}

function dev4press_add_tax_terms($object_id, $terms, $taxonomy = 'post_tag') {
 global $wpdb;

 foreach ($terms as $term) {
 if (!strlen(trim($term))) continue;
 $term_info = dev4press_term_exists($term, $taxonomy);
 if (is_null($term_info)) {
 $term_info = dev4press_insert_term($term, $taxonomy);
 }
 $tt_id = $term_info['term_taxonomy_id'];
 $wpdb->insert($wpdb->term_relationships, array('object_id' => $object_id, 'term_taxonomy_id' => $tt_id));
 wp_update_term_count(array($tt_id), $taxonomy);
 }
}
?>

Conclusion

This is not something that you will need for every website, but it’ a good idea to have this around if you are working on not so typical WP website where using core code can cause website to be slow.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/adding-large-number-of-terms/feed/ 2
Get posts for a category http://www.dev4press.com/2010/tutorials/wordpress/tips/get-posts-for-a-category/ http://www.dev4press.com/2010/tutorials/wordpress/tips/get-posts-for-a-category/#comments Sat, 25 Sep 2010 10:57:08 +0000 MillaN http://www.dev4press.com/?p=3254 This is basic operation in WordPress, but it’s not as straightforward as you might think. For that, you will usually use get_posts() function that allows you to set category, but this function can use many more options than actually documented, you can use all WP Query arguments with it.

We will see how to exclude child categories from results and how to do a bit more with some other additional arguments this function can use.

Basic category settings in get_posts()

If you follow get_posts() documented arguments, without going any deeper, you will see that you can specify category by ID:

<?php
$posts = get_posts(array('category' => 1));
?>

And this will get you 5 posts from specify category and ALL child categories belonging to that one! If you need more than 5 or if you need all, you must set number of posts to get:

<?php
$posts = get_posts(array('numberposts' => 10000, 'category' => 1));
?>

This will get you up to 10.000 posts from category with ID 1 and ALL child categories belonging to it.

Additional categories arguments

But, in many cases you don’t want posts belonging to child categories, you want posts that are specifically assigned to a category. Well, in that case this method is no good. Or is it? Well, you can still use same function, but this time with arguments that were not documented for that function.

<?php
$posts = get_posts(array('numberposts' => 10000, 'category__in' => array(1)));
?>

Now we are getting somewhere. This will limit results only to category with ID 1, and will ignore any child categories this one might have. You can specify more than one category as a value for category__in argument and that will get you posts that belong to at least one of the categories in array.

There are few more arguments that you will find interesting for getting posts in categories.

<?php
$posts = get_posts(array('category__and' => array(1, 5, 42)));
$posts = get_posts(array('category__not_in' => array(3, 71)));
?>

Line 2 uses category__and argument, and this one will get you posts belonging to all specified categories. If a post belongs to 1 and 5 only and not 42 it will not be used. Only posts belonging to 1, 5 and 42 are returned.

Line 3 uses category__not_in argument, and this will return posts not belonging to specified categories. In all this cases, you must specify the category ID’s.

And more

For a full list of arguments you can use with get_posts() function, you can check out this article from Codex:
http://codex.wordpress.org/Function_Reference/query_posts

]]>
http://www.dev4press.com/2010/tutorials/wordpress/tips/get-posts-for-a-category/feed/ 6
Internal objects cache in WordPress http://www.dev4press.com/2010/tutorials/wordpress/practical/internal-object-cache-in-wordpress/ http://www.dev4press.com/2010/tutorials/wordpress/practical/internal-object-cache-in-wordpress/#comments Sun, 05 Sep 2010 14:38:24 +0000 MillaN http://www.dev4press.com/?p=3101 To speed things up, WordPress uses internal caching methods for storing object, queries for potential reuse. Use of cache will speed up normal operations of WordPress. Bot, there are cases where use of cache is not wanted and can cause tons of problems.

How the internal cache works?

Whenever WordPress runs function(s) that get posts, pages, categories or any other data object, result is than stored in instance of the WP_Object_Cache class. Each object is stored in it’s own group and it’s identified by ID. So, if you get post ID 1, it will be stored in this class instance. Next time on the same page, you need again same post, WP will search for it in the cache, and if it’s there it will get it for you, if not SQL query will be run to get it. Depending on number of stored objects, this cache can grow significantly.

Instance  of class WP_DB is main database object, and also stores all SQL queries executed through it. Most WP pages run 10 to 200 or so queries, and queries are stored as strings. With small number of queries this object can grow to couple of megabytes. For this object you can disable saving queries, but in many cases plugins will enable it, so you can’t be sure really that queries are not stored.

And all this is great if you only have code to generate pages, normal admin use, in fact normal use of  WordPress. If you have couple of hundreds or even thousands of posts/pages, none of the normal WP operations will cause problems with use of cache. But, what if you have website with 200.000 or more posts?

Out of memory problems

For large websites, first piece of code that will fail even if you use 256M for PHP is Google XML Sitemaps plugin when attempts to make a XML file. To get URL for each post, it will run get_permalink() function, that is running get_post() that is caching objects. So, each post will be cached even if it’s used only once. And when plugin reaches 70.000 posts (approx.), PHP will run out of memory, and all 256M will be used! Not only posts, but all SQL queries will be stored. And for 70.000 posts, in this case WP can run more than 100.000 queries.

I am working on website that has 300.000 posts, sitemap generating  crashes at 65.000 with 256M used up. So, I made a new code that controls sitemap: splits sitemap in new file at every 50.000 posts (Google limit per sitemap is 50.000), and also is clearing cached data to prevent out of control use of memory.

Solution for clearing cache

Website I work on has several cleanup and processing operations that will generate large amount of queries and cache many objects during each run. Using cache will break it for sure on every run. But, in WordPress right now there is no way to disable cache. It would be good that directive like WP_DISABLE_CACHE is added to control this. And until that is done, only way to control it is actually to delete cached object. So, my processing code and also sitemaps code is using simple function to clear cache from time to time.

Here is the function that will clear cache object and stored queries:

<?php
function wp_clean_cache_full() {
  global $wpdb, $wp_object_cache;

  unset($wp_object_cache->cache);
  $wp_object_cache->cache = array();
  unset($wpdb->queries);
  $wpdb->queries = array();
}
?>

Conclusion

This is not something that you will need all the time, but it’s good thing to know what can cause website crashes that you can’t understand at first. Out of memory problems are common with large websites if the data is not handled properly.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/internal-object-cache-in-wordpress/feed/ 2
Improve your WordPress website speed, Part 1. http://www.dev4press.com/2010/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-1/ http://www.dev4press.com/2010/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-1/#comments Tue, 31 Aug 2010 15:28:00 +0000 MillaN http://www.dev4press.com/?p=3038 Generally speaking WordPress is fast. And this is the case even with large websites with tens of thousands of posts. Mostly, speed depends on the theme and than on the plugins. But in many cases the slowest part is the WordPress core. Here is how to speed it up.

SQL execution background

Most of the SQL queries WordPress uses are fast. They will get slower with more complex filters added to the query, but such queries are rare. In most cases you can’t do much to speed them up. Some of the operations WordPress runs will execute more than one query: filtering posts by category or tag, metadata queries. This is done because 2 simpler queries are usually faster than one query using joins.

When number of posts rises, queries will tend to slow down. If the query relies on columns that are indexed (post ID for instance), speed will remain the same and number of posts will not affect speed. But, in some cases queries will rely on columns that are not indexed or even if they are indexed, index is not having effect. Such columns are ususally date/time columns.

Speed problems

While main SQL queries will usually remain fast, even with default configuration of WordPress, default theme and usual plugins, there are SQL queries in the WordPress core that are very slow. And most of the are not needed at all. This time we will focus on SQL queries that are part of the page header. Using filters WordPress core adds several functions to the header that are used to generate additional tags. These tags are adding additional URL’s inside the website: previous post, next post, parent post (for hierarchical post types), first post in category. These filters can generate 5 to 10 SQL queries, and in some cases they can take longer to execute than all the other SQL queries on the page combined!

These header tags look something like this:

<link rel='index' title='Dev4Press Premium Plugins and Themes' href='http://www.dev4press.com/' />
<link rel='start' title='Plugins' href='http://www.dev4press.com/category/plugins/' />
<link rel='prev' title='GD Press Tools' href='http://www.dev4press.com/plugins/gd-press-tools' />
<link rel='next' title='GD Star Rating' href='http://www.dev4press.com/plugins/gd-star-rating' />

Browsers can use (but mostly don’t) these to prefetch pages while you browse the website based on these links. I am not aware of any other important use for them. I always disable these, because I don’t see any real and useful reason to have them in the first place.

Adjacent Posts filter uses date column in the post (twice), and that is not as fast as other types of indexed columns are. When a website is small it’s not a problem. But on a website with few thousands or more than 10.000 posts this will cause trouble. I am working on a website with 250.000 posts. This action and 2 queries it generates can take more than 2 seconds to run on a very fast dedicated VPS server. Add to it other header link queries, and they can take more than 3 seconds to run. And that is just too much. Things get just much worse in case of hierarchical post types.

Solution

Simple. Remove the filters. If you don’t have any use for this header links you can remove the filters. I measured some of the pages. In some cases page took 3.54 seconds to execute all SQL queries. Then, I disabled these filters, and SQL queries are executed in 0.02 seconds. Also, page needs now 7 SQL queries less. If you want to manually add code to remove the filters, add this to your theme functions.php or your plugin. It’s better to run this on init action, I had some conflicts if executed before.

<?php
add_action('init', 'remove_header_links_actions');
function remove_header_links_actions() {
  remove_action('wp_head', 'index_rel_link');
  remove_action('wp_head', 'parent_post_rel_link');
  remove_action('wp_head', 'start_post_rel_link');
  remove_action('wp_head', 'adjacent_posts_rel_link');
  remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
}
?>

If you don’t like messing with the code, you can use my GD Press Tools plugin (only Pro edition has the options to remove these: plugin Settings -> Content -> Header). Also, my xScape based premium themes have options to disable these actions, it’s built into the framework so all my themes have it.

Conclusion

I will search further for more things you can do to optimize websites, so more posts like this will be added. If you have some more suggestions on WordPress speed improving, please leave a comment.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/practical/improve-your-wordpress-website-speed-part-1/feed/ 4
Add rich text editor to your plugin http://www.dev4press.com/2010/tutorials/wordpress/tips/add-rich-text-editor-to-your-plugin/ http://www.dev4press.com/2010/tutorials/wordpress/tips/add-rich-text-editor-to-your-plugin/#comments Wed, 21 Jul 2010 22:15:03 +0000 MillaN http://www.dev4press.com/?p=2651 Editor Example

Editor Example

Sometimes is very useful to be able and use existing WordPress rich editor within your plugins. TinyMCE editor built in WP can be easily reused and you can even set some elements. Following example will work in WordPress 2.8 and newer including latest WP 3.0.

There are two parts to this procedure. One is to load needed JS and CSS files, and other to call the editor where you want it displayed.

Loading Editor

To load TinyMCE you need to use the following code. First two lines attach hooks to init and head actions. Two functions hooked follow after. One loads JavaScript needed, and second actually loads the editor. Line that enqueues the media upload element is needed only if you use media buttons.

<?php
add_action('admin_init', 'editor_admin_init');
add_action('admin_head', 'editor_admin_head');

function editor_admin_init() {
  wp_enqueue_script('word-count');
  wp_enqueue_script('post');
  wp_enqueue_script('editor');
  wp_enqueue_script('media-upload');
}

function editor_admin_head() {
  wp_tiny_mce();
}
?>

Display editor

Editor is displayed using one function. This function is defined as follows:

the_editor($content, $id = ‘content’, $prev_id = ‘title’, $media_buttons = true, $tab_index = 2)

First parameter, $content will be displayed inside the editor. Next is $id, and the textarea element created will have that ID. You can use it to get the content from the editor. Next parameter can be used the specify previous element in the form for tab moving (last parameter). And, $media_buttons allow you to display or hide media upload buttons above the editor.

Here is an example:

<div id="poststuff">
<?php
  the_editor("", "content", "", true);
?>
</div>

This you need to add on your panel where you want editor displayed. It will fit into any DIV you want so that you can limit the size and dimenzions. Using “poststuff” DIV is important so that all elements are styled properly.

Content of the editor is available as part of the form on submit named as content, or whatever you set as ID in the code above. If you want to access to content from JavaScript use this:

tinyMCE.activeEditor.getContent();

That’s all you need to know (for now), you can use anything tinyMCE object offers from JavaScript. If you need more help, leave a comment.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/tips/add-rich-text-editor-to-your-plugin/feed/ 79
Be careful naming FORM fields in WordPress http://www.dev4press.com/2010/tutorials/wordpress/tips/be-careful-naming-form-fields-in-wordpress/ http://www.dev4press.com/2010/tutorials/wordpress/tips/be-careful-naming-form-fields-in-wordpress/#comments Fri, 16 Jul 2010 22:02:35 +0000 MillaN http://www.dev4press.com/?p=2629 When you create a complex form that will be used on page or anywhere in WordPress, there are some restrictions that you will not found documented, and will cause you a lot of problems if you are not aware of them and how to solve them.

I am working on a project and a page with form, and form required a field for year of birth. Form I made was submitted using POST method. And I named the field for year of birth, simply: year. And I set the year field and submit the form, and instead form getting saved, I am redirected to 404 page. If I don’t set year field, everything is OK.

It took me some time to realize that WordPress is parsing the requests (even POST) and uses elements if they are recognized as rewrite elements. And year is one of the elements used to create rewrite rules. I renamed field to birth_year and everything was working fine. I didn’t had the time to test with older version of WordPress, but this problem is present in both WordPress 2.9 and WordPress 3.0.

This is a problem that can even be considered as bug, because parsing POST request for URL parameters is not needed. Only if the form is submitted as GET, these parameters can cause trouble.

So, to avoid problems with naming the form fields don’t use reserved keywords (even so they are not actually reserved, they might as well be) like:
year, monthnum, day, hourminutesecond, postname, post_id, pagename, category, tag, author, pagename and search.

Each of the field elements named using keywords in bold above, with value set will break the form and cause redirection problems, usually ending at 404 page.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/tips/be-careful-naming-form-fields-in-wordpress/feed/ 0
Migrate from WPMU 2.9.2 to WP 3.0 MultiSite http://www.dev4press.com/2010/tutorials/wordpress/various/migrate-from-wpmu-2-9-2-to-wp-3-0-multisite/ http://www.dev4press.com/2010/tutorials/wordpress/various/migrate-from-wpmu-2-9-2-to-wp-3-0-multisite/#comments Thu, 27 May 2010 21:58:59 +0000 MillaN http://www.dev4press.com/?p=2247 WordPress 3.0 will be released very soon, and there are many websites that run WPMU versions of WordPress, that need to be migrated to new WP 3.0. I have no idea if the development of WPMU will continue in any form, but most likely it’s over and migration is a must. So, here is the step by step info on how to upgrade your WPMU to WP 3.0. Tutorial will assume that you use default installation of WPMU with default folder names, database prefixes and everything else.

Upgrade Procedure

Backup your current WPMU website installation and the database before you proceed with the upgrade.

  • Start with ‘wp-config.php’. You need to add 2 new lines into it:
    define('WP_ALLOW_MULTISITE', true);
    define('NONCE_SALT', 'unique_string_for_salt_use');

    Nonce salt is not part of WPMU 2.9.2, and you need to add that one. You can use salt that WPMU generated and stored in database (can be there, but also it might not be). It is the ‘nonce_salt’ key in the ‘wp_1_options’ table. You can copy value from that record to the the define. You can also use this from WP 3.0 installation you maybe have. Adding salt can be skipped and added at the end per recommendation of WP upgrade network process. There is one more define that is not needed, but….

    define('MULTISITE', true);

    MULTISITE line is not needed, but in some cases it’s added with the fresh install of WP 3.0 Multisite. At least that was with Beta versions. I will investigate if it’s needed really or not.

  • Next is ‘.htaccess’ file. Main part needed for WP is very similar, and the main difference is line 6 used for files. You can safely change only that line in your old ‘wp-config.php’. This is how the rewrite portion of the htaccess should look like now.
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    
    # uploaded files
    RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
    
    # add a trailing slash to /wp-admin
    RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule  ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
    RewriteRule  ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
    RewriteRule . index.php [L]
  • Now you need to replace all WordPress files. To get the latest WP 3.0 go to the official WP website, but since it’s not released yet, you can get it from SVN. Delete folders ‘wp-admin’ and ‘wp-includes’, and delete files ‘wpmu-settings.php’ from root folder, and ‘blogs.php’ from ‘wp-content’ folder. Now you can copy over all the WP 3.0 files and folders, and replace the remaining files.
  • Make sure that there is ‘blogs.dir’ in ‘wp-content’ folder. If you changed that using ‘wp-config’ check to see if those are still in the file and set properly.

That’s all the upgrading you need to do. After this, your website should be working. When you login for the first time, you will get a message that you need to upgrade network (that’s new name for site used in WPMU, and term site is replaced blog). Once you do that, everything should be fine. If something else needs to be done, WP will inform you during this network upgrade process.

Troubleshooting

If you use latest nightly build from SVN, things should be OK. There are reports that upgrade didn’t go smoothly for everyone with older builds and there were problems with prefixes used for tables in the database. In WPMU default blog was ID 1 and prefix wp_1_, and in WP 3.0 it’s still ID 1 but prefix is only wp_. With latest builds WP 3.0 sorts this out just fine, but if you have troubles with this check out the resources listed at the end of this tutorial. If you have any additional questions, ask in the comments.

Resources

Edit

  • 2010.05.29: added MULTISITE define for wp-config.php.
]]>
http://www.dev4press.com/2010/tutorials/wordpress/various/migrate-from-wpmu-2-9-2-to-wp-3-0-multisite/feed/ 5
Use Firebug to track AJAX requests and responses http://www.dev4press.com/2010/tutorials/wordpress/various/use-firebug-to-track-ajax-requests-and-responses/ http://www.dev4press.com/2010/tutorials/wordpress/various/use-firebug-to-track-ajax-requests-and-responses/#comments Mon, 24 May 2010 14:09:10 +0000 MillaN http://www.dev4press.com/?p=2222 Whenever you use JavaScript powered application, data is usually transported using AJAX from the server to the client side. During that process, errors can occur on the server side to cause application to fail. Firebug is extension for Firefox that can help us track these problems.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/various/use-firebug-to-track-ajax-requests-and-responses/feed/ 1
Translating plugins or themes using POEdit http://www.dev4press.com/2010/tutorials/wordpress/various/translating-plugins-or-themes-using-poedit/ http://www.dev4press.com/2010/tutorials/wordpress/various/translating-plugins-or-themes-using-poedit/#comments Thu, 06 May 2010 13:51:32 +0000 MillaN http://www.dev4press.com/?p=2090 All our plugins and theme have multi-language support. To create new translation, best program available is POEdit, a free program that will help you create valid translation files. This program will help you create translation, and later update it when the new version is released.

Step 1: Installing the POEdit

You need to download latest version of the program from: http://www.poedit.net/. Installation is simple much like any other program. There are versions for Windows, Linux and Mac OS so you can work on any platform with it.

Step 2: Creating new translation project

In File menu you have option ‘Create catalog from POT file’. Dialog will appear and you need to give it POT file you want to translate. Program will ask you for the project info, and here you can add info about project, translation language and yourself. After that you need to save catalog. You can use default name for now, we can rename file later. And, now if POT file is valid, you will see the list of translation strings. If the POT file is not valid you will get information about errors.

GD Star Rating always includes latest POT file with all the strings in the current plugin version, and will use this plugin as an example. This file is: gd-star-rating.pot and is in the main plugin folder.

Step 3: Translating

This is pretty obvious, you need to translate all strings. Below the list, you will see two two fields, one with original string, and the other for your translated string. Right click on any string in the list, will show you comments for that string, and usually that is location of the string in the original files, in our case plugin or theme. You can also copy value of original string into translated string.

Important: Don’t translate %s you found embedded in the strings for translation, just leave them. They represent some other value added by the plugin or theme code, usually numbers or something else.

Step 4: Proper naming of translation files

Once you complete translation, you need to save it. Program will generate two files. One with extension MO and other PO. Both files should have the same name, only different extension. Name of the file also need to have a language code. So, here is the example of proper named files for Serbian translation:

  • gd-star-rating-sr_RS.mo
  • gd-star-rating-sr_RS.po

As you can see, main part is the same as the name of POT file, than you add minus sign and after that language code. Full list of these codes can be found here: http://codex.wordpress.org/WordPress_in_Your_Language. All our plugins and themes use this naming convention.

Plural settings

Plural settings

Step 5: Setting for plural forms

This is a step dependent on the language you translate into. For most languages, there is a singular and plural words (2 plural forms). Some, like Russian have 3. Before you start translating, you need to set this first. When you create empty translation, or you want to change existing to support plurals, open Catalog menu, and in that menu open Settings. You need to fill plural form part. For most languages this is:

nplurals=2; plural=n != 1;

To get more info on the subject, check out this post: Translating Plural Forms with Poedit.

Plural translate

Plural translate

Once you set plural form, when you get to translate plural word, main POEdit form will look a bit different, as shown on the image on the left, with singular and plural boxes and two form elements to translate them.

Step 6: Updating the translation

When the plugin POT files is updated, you need to update your translation files. Once you receive new POT file, you need to open PO file of your translation (‘gd-star-rating-sr_RS.po’) in POEdit and use ‘Update from POT file’ option in ‘Catalog’ menu. Point to POT file, and program will show you what is new and will add this new strings for you to translate. Also, will show you what is became obsolete, and will remove old and no more needed strings from your translation. Program will try to recognize the changes and offer you the ‘fuzzy’ translation.

]]>
http://www.dev4press.com/2010/tutorials/wordpress/various/translating-plugins-or-themes-using-poedit/feed/ 47
Better permalink rewrite code http://www.dev4press.com/2010/tutorials/wordpress/tips/better-permalink-rewrite-code/ http://www.dev4press.com/2010/tutorials/wordpress/tips/better-permalink-rewrite-code/#comments Sat, 09 Jan 2010 11:59:06 +0000 MillaN http://www.dev4press.com/?p=1210 Most blog powered by WordPress use ‘pretty’ links structure. This allows you to have hierarchical structure of the URL elements and that is much easier to read, and can even contribute to SEO results. And to achieve this WP adds rewrite code into htaccess.

Original WordpRess code is this:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

And, this is usually left as it is, and it works just fine. But, this actually can be better and not only that, changing this piece of code can speed up your blog by avoiding some of the unneeded file and folder checks that rewrite module will perform based on the original WordPress code.

JP Morgan has suggested modified rewrite code to be used in the htaccess that will perform much better:

# BEGIN WordPress
RewriteEngine on
#
# Unless you have set a different RewriteBase preceding this point,
# you may delete or comment-out the following RewriteBase directive
# RewriteBase /
#
# if this request is for "/" or has already been rewritten to WP
RewriteCond $1 ^(index\.php)?$ [OR]
# or if request is for image, css, or js file
RewriteCond $1 \.(gif|jpeg|jpg|png|ico|css|js)$ [NC,OR]
# or if URL resolves to existing file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# or if URL resolves to existing directory
RewriteCond %{REQUEST_FILENAME} -d
# then skip the rewrite to WP
RewriteRule ^(.*)$ - 
# else rewrite the request to WP
RewriteRule . /index.php [L]
# END wordpress

On line 11 you see a number of extensions that will be excluded from rewrite checking. It’s not good to have too many extensions here because they cam have negative impact. Images, CSS and JS are enough to have here. This new code also removes IfModule check. If you already have mod_rewrite this check is useless, if you don’t have mod_rewrite than you need to turn of the permalinks in the WordPress. You can safely remove all lines starting with #, they are only comments.

Actually speedup gain depends on many factors: size of the website, speed of the server and things like that. If you have small blog, speedup will be small, but in many cases you will be able to notice it. JP Morgan claims that htaccess processing with changed code is cut in half and that has great positive effect on the website performance. I tested the code on two websites for now, and it works good, and some speed gains can be measured.

Source at WebmasterWorld.com: http://www.webmasterworld.com/apache/4053973.htm

]]>
http://www.dev4press.com/2010/tutorials/wordpress/tips/better-permalink-rewrite-code/feed/ 1
Using Custom Taxonomies http://www.dev4press.com/2009/tutorials/wordpress/tips/using-custom-taxonomies/ http://www.dev4press.com/2009/tutorials/wordpress/tips/using-custom-taxonomies/#comments Tue, 28 Jul 2009 01:43:41 +0000 MillaN http://www.dev4press.com/?p=568 With WordPress 2.8 we got another interesting feature called custom taxonomies. You can make taxonomies from anything you want and use them much like you already use tags and categories. Unfortunately, themes offer only partial support (unsolvable problem) for custom taxonomies, but it’s not that complicated to implement.

When the first custom taxonomies were announced I wasn’t a big fan of the idea. Also, in the beginning custom taxonomies were very buggy, and hard to test. But, fortunately that’s now changed, and with 2 minor revisions it looks very stable. I have been interested in the way all that works, but I didn’t had a real chance to use custom taxonomies.

But now, I am working on new website, and using custom taxonomies came so natural and easy that I changed things a bit so I can use more of them for different types of data. Before I proceed on actual example on how to use it, I will try to explain exactly what you get bu using custom taxonomies.

As you know tags are widely used and very important on  any blog. But, tags are too wide and anything can be a tag. It’s not that specific as you might need. Same problem is with categories. In many cases you will need to add more specific, more targeted version of tags or even categories. Custom taxonomies can help you do just that. Let’s say that you want to make a website about movies. And you need to have a posts about movies. First thing you might wanna do is to make categories with movie genres. But that’s not that good solution when you have movies belonging to more than one genre. Also, you might wanna use categories for some more things. So, you create a custom taxonomy for genre. Similar will be with actors and directors. What’s the biggest benefit from this? If you have a lot of movies, you will have several movies directed by the same director. You can query all posts based on the director name and get all movies directed by him. Same goes for actors, and genres. Since archives template in theme already handles tags and categories, it will do just fine with custom taxonomies and you can easily get the archive page with post from a director or belonging to specific genre.

So, here is how to add these 3 custom taxonomies. You can do this from theme or plugin, all the same. If you use theme method, most logical location is functions.php.

add_action('init', 'init_taxonomies');

function init_taxonomies() {
register_taxonomy('genres', 'post', array('hierarchical' => false, 'label' => 'Genres', 'query_var' => true, 'rewrite' => true));
register_taxonomy('actors', 'post', array('hierarchical' => false, 'label' => 'Actors', 'query_var' => true, 'rewrite' => true));
register_taxonomy('directors', 'post', array('hierarchical' => false, 'label' => 'Directors', 'query_var' => true, 'rewrite' => true));
}
Taxonomies Widgets

Taxonomies Widgets

This will ensure that Post menu will be expanded to include all custom taxonomies you added, and that post edit page widgets for each one is added. You can see the two widgets on the image on the right. As you can see there are many parameters for adding taxonomy. First you give taxonomy short name (no spaces or special characters), and then you have array with settings. Hierarchical will be used to create new taxonomy to look like tags or like categories that support hierarchy. Label is the name used in menus or widgets. Query_var and Rewrite will add taxonomy to WP_Query object and to rewriter, and I suggest leaving that active.

Post menu will be expanded with new panel for each taxonomy, and this panel looks like tags or categories panel, and works the same.

Out of the box new archives URL’s should be working also, so you can use url like this one:

http://www.website.com/actors/ben-browder/

And you will get all posts that have actors taxonomy Ben Browder. This will get all movies that this actor starred in. Simple as that. The same way WP_Query gets new variable for each of the taxonomies you can also use, or to get tag cloud. Here are few examples:

get_the_term_list($post->ID, 'actors', 'Actors: ', ', ', '' );
wp_tag_cloud(array('taxonomy' => 'actors', 'number' => 20));
query_posts(array('actors' => 'ben-browder'));

First will get you list similar to tags list for the post in the theme, second render widget-like tag cloud, and the third one is example of query_posts functions, and will pull posts for Ben Browder.

And for the end of the post, here is the list of some useful URL’s:

http://codex.wordpress.org/Function_Reference/register_taxonomy
http://codex.wordpress.org/Function_Reference

The easiest way to work with taxonomies is to use our GD Taxonomies Tools plugin:

http://www.dev4press.com/plugins/gd-taxonomies-tools/

]]>
http://www.dev4press.com/2009/tutorials/wordpress/tips/using-custom-taxonomies/feed/ 6