Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have seen a number of similar questions here on WP_SE but I believe my situation is a little different because the common libraries I'm creating are frameworks that I'd certainly like to be able to update and maintain, but are not decorations - ie: I can't author a theme that depends on the library and then degrade the theme nicely if the library isn't found.

Common Libraries

I have a set of utility functions and some classes that I have developed to really speed up certain aspects of WordPress customization. I have been using them extensively in custom themes, and they are then usually bundled in some subdirectory of the theme.

Now I'm writing a plugin and I want to use those libraries in the plugin. The logical place for them in the case of plugins would be inside some kind of lib/ or include/ folder inside my plugin's directory structure.

The problem of course is that if I'm using both the plugin and the theme, the functions and classes are all being declared twice and that throws an error. Require_once doesn't realize these are the same codebase because of the different paths.

One solution would be to bundle all these libs into a separate plugin, and have the theme and the plugin leverage this utility plugin. But because these libs are essential to the theme/plugin's operation, the plugin must be installed when the theme/plugin is in use. Thinking forward, I don't want someone to have to download and install my theme and then download and install a plugin so that the theme will work. So that solution seems out of the question for me.

Can a theme or plugin go and fetch another plugin and install it? Can the theme installation process write to a directory other than wp-content/themes? same with the plugin activation process?

share|improve this question
    
Just wanted to point out that I read wordpress.stackexchange.com/questions/2174/… and others and I think there has to be another solution for "framework" type plugins. –  Tom Auger Oct 13 '11 at 20:34
    
I am not entirely convinced this is not a duplicate of question you mention. I covered alternatives such as conditional loading and more complex multi-version loading. That would probably be my answer for this question as well. –  Rarst Oct 13 '11 at 20:53

2 Answers 2

up vote 3 down vote accepted

Can a theme or plugin go and fetch another plugin and install it?

For themes, it's rather straighforward. See https://github.com/thomasgriffin/TGM-Plugin-Activation

For plugins, it's trickier, since you can't bundle the same boilerplate code in more than one plugin. See http://wordpress.org/extend/plugins/plugin-dependencies/

share|improve this answer
    
Awesome, @scribu, thanks for the TGM-Plugin-Activation link. Very cool. I have seen some other plugins (GDStarRatings for example) actually create their own directory inside wp-content and install their libs there. What do you think about that practice? –  Tom Auger Oct 14 '11 at 21:00
    
If you do it properly, asking for the FTP credentials if necessary (like for normal plugin installs), it's a viable alternative, although might be confusing to the user. –  scribu Oct 15 '11 at 3:03
    
Just remember that the boilerplate code that handles the lib installation must be conditionally loaded. –  scribu Oct 15 '11 at 3:10

Method #1: Create a plugin that just loads your library and place it in the /wp-content/mu-plugins (these get loaded automatically before regular plugins/themes) folder. Then remove your library from everywhere else.

Method #2 (best way): Safeguard your functions and classes declarations to prevent name collision.

if(!function_exists('unduplicatable')):
    function unduplicatable(){
        // Add code here
    }
endif;

or:

if(!class_exists('unduplicatable')):
    class unduplicatable(){
        // Add code here
    }
endif;

or

if(!isset($global_variable)):
    // Prevent double initializations
    $global_variable = array();
endif;

Regards.

share|improve this answer
    
Method #2 may seem like a good idea, but when you start having multiple versions of the same function, it's hell trying to figure out which one was loaded. –  scribu Oct 14 '11 at 3:25
    
That's just to protect from the name collision issues. If you need a shared codebase, you need a library in a mu plugin. Usually you don't worry about this if you use code provided by others. The issue mentioned occurs only when you write your own code and plugins, as I do. I have a shared library to hold all shared functions. If you start having versioning issues in your own codebase, you've got a problem... and you're the problem. –  EarnestoDev Oct 14 '11 at 3:52
    
What I meant was including the same function in multiple plugins, releasing new versions of those plugins (and of that function) and then having users use old versions of some plugins and new versions of others. –  scribu Oct 14 '11 at 5:51
    
This is why I HATE autoupdate (first make sure it works then update). Issues with versioning can be fixed with namespaces. But, having public plugins, all dependencies should be embedded and all functions should have specific names. –  EarnestoDev Oct 14 '11 at 11:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.