This entry is part 1 of 9 in the User Submitted Image Galleries Series
- User Submitting Gallery Images – Part 1
- User Submitted Gallery Images – Part 2
- User Submitted Image Gallery – Part 3
- User Submitted Image Gallery – Part 4
- User Submitted Image Gallery – Part 5
- User Submitted Image Gallery – Part 6
- User Submitted Image Gallery – Part 7
- User Submitted Image Gallery – Part 8
- User Submitted Image Gallery – Final Overview
In part one of the User Submitted Image Galleries tutorial series, I’m going to walk you through the beginning steps of setting up our User Image Gallery plugin. This is a plugin that will allow us to have a user-submitting gallery of images our website. If a user registered an logged-in, they will be able to hav a portfolio of all images they have uploaded. Non logged-in users will be able to submit images as guests. The plugin’s functions will closely mirror the system I built for CG Cookie, Inc.
The gallery system is going to work with custom post types, so each image in the gallery will be an entry in the custom post type. We will also be setting up a set of custom taxonomies: one that will allow us to categorize the images, and one that will allow us to tag the images, much like the default Post Categories and Tags.
This first part of the series will cover setting up the post types and taxonomies, as well as a few of the plugin options and files. Once complete, the plugin will consist of seven to ten files and will cover a large array of functions.
So, to begin, let’s setup our plugin folder / file structure. Create a folder called “user-image-gallery”. This is the folder we will place all of out plugin files in. Place this folder in your wp-plugins/ directory. Next, create a .php file called user-image-gallery.php, and save it in the folder you just created. And lastly, create two more folders inside the first, one called includes, and one called languages.
Your folder should mirror mine:
Now, open user-image-gallery.php in your favorite code editor. We are going to make WordPress recognize our file as a plugin by adding the plugin header information. This is standard for every WordPress plugin, so if you’re not familiar with this, then I highly suggest you read my Writing Your First WordPress Plugin tutorial series.
1 2 3 4 5 6 7 8 9 10 11 | <?php /* Plugin Name: User Image Gallery Plugin URI: https://pippinsplugins.com/series/user-submitted-imag-galleries/ Description: A public image gallery system for WordPress that allows users to upload their own images and have a portfolio of all their uploads Text Domain: uig Domain Path: /languages/ Author: Pippin Williamson Author URI: https://pippinsplugins.com Version: 1.0 */ |
Our plugin will now be available for activation in WordPress, even though it won’t do anything at this point.
Setting Up Plugin Constants
Constants are variables that never change. In plugin development, they great to use for defining variables that contain the URL and path of our plugin directory, as well as things like our plugin prefix. We will define three constants, and they will be used throughout the plugin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // plugin prefix if(!defined('UIG_PREFIX')) { define('UIG_PREFIX', 'uig_'); } // plugin folder url if(!defined('UIG_PLUGIN_URL')) { define('UIG_PLUGIN_URL', plugin_dir_url( __FILE__ )); } // plugin folder path if(!defined('UIG_PLUGIN_DIR')) { define('UIG_PLUGIN_DIR', dirname(__FILE__)); } |
We’re first checking to make sure our constants are not defined, with the defined(), and then, if they are not, we’re defining each of our constants with the define() function.
The plugin folder URL will used when loading scripts, such as JS and CSS files, and the plugin folder path will be used when including plugin files into other plugin files. Both of these constants will point to wp-plugins/user-image-gallery, without a trailing slash.
Loading Our Plugin’s Text Domain
In order to make our plugin ready for translation, we need to load the plugin’s text domain. This is done with the load_plugin_textdomain() function.
1 2 3 4 5 | /******************************************* * plugin text domain for translations *******************************************/ load_plugin_textdomain( 'uig', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); |
This will take care of displaying our plugin in the user’s selected language, if the translation files exist inside of the languages folder.
Localizing and translating plugins is a large topic, so I’m not going to cover how it’s done in this tutorial, just know that we are making our plugin completely ready for translation. If you would like to learn how, then read the link above.
The Includes Section
If you have ready my Writing Your First Plugin series then you will know that I always separate my plugins into multiple files. This is a really easy way to keep your plugin organized, which is very important when writing larger plugins, such as the one we’re writing here. I separate my plugin’s functions by type (or functionality) and then place them into meaningfully named files.
In this plugin, we will have quite a few different files, and they will all be “included” into the main plugin file (the one we were working with above). I always put all of my includes in the same place. So that’s what we’re going to do now:
1 2 3 4 5 | /***************************************** Includes *****************************************/ include(UIG_PLUGIN_DIR . '/includes/our-file-name.php'); |
This will “pull” the contents of the “our-file-name.php” file into our main plugin file, making its functions available for use. Note that the UIG_PLUGIN_DIR constant points to our plugin’s main directory.
So let’s now create our first real file to be included and load it up.
Create a new file called “post-types.php” and save it into the includes/ folder. Next, load it like this:
1 | include(UIG_PLUGIN_DIR . '/includes/post-types.php'); |
This file will hold all of our custom post type and taxonomy registration functions.
Registering the Post Types and Taxonomies
Our plugin is going to be based around a custom post type for our gallery images, so we need to register that post type. Since there are countless tutorials out there that explain how to create a custom post type, I’m not going to go line by line and explain it. If you need it, this search should help you out.
First, open the post-types.php file and place this at the top:
1 2 3 4 | <?php /***************************************** UIG Post Type and Taxonomies *****************************************/ |
It’s just a comment to help us know what is in this file.
Now we’re going to write a function that will register our custom post type for us:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | function uig_create_post_types() { $image_labels = array( 'name' => _x( 'Images', 'post type general name' ), 'singular_name' => _x( 'Image', 'post type singular name' ), 'add_new' => _x( 'Add Image', 'uig_image' ), 'add_new_item' => __( 'Add Image', 'uig' ), 'edit_item' => __( 'Edit Image', 'uig' ), 'new_item' => __( 'Add Image', 'uig' ), 'view_item' => __( 'View Image', 'uig' ), 'search_items' => __( 'Search Images', 'uig' ), 'not_found' => __( 'No Images found', 'uig' ), 'not_found_in_trash' => __( 'No Images found in Trash', 'uig' ), 'parent_item_colon' => '' ); $image_args = array( 'labels' => $image_labels, 'singular_label' => __('Image', 'uig'), 'public' => true, 'show_ui' => true, 'has_archive' => 'images', 'capability_type' => 'post', 'hierarchical' => false, 'exclude_from_search' => false, 'rewrite' => array('slug' => 'images'), 'supports' => array('title', 'editor', 'revisions', 'comments', 'author', 'thumbnail'), 'menu_position' => 5 ); register_post_type('uig_image', $image_args); } add_action('init', 'uig_create_post_types'); |
Our “Images” post type will now be available in the dashboard.
Next, we need to create our taxonomies. This is a very similar process, and once again, I’m not going to explain how to register the taxonomies, since there are countless tutorials out there already.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | // set up our images custom taxonomies function uig_register_image_taxonomies() { // set up the image Categories $labels = array( 'name' => _x( 'Categories', 'taxonomy general name' ), 'singular_name' => _x( 'Category', 'taxonomy singular name' ), 'add_new' => _x( 'Add New Category', 'Category'), 'add_new_item' => __( 'Add New Category', 'uig' ), 'edit_item' => __( 'Edit Category', 'uig' ), 'new_item' => __( 'New Category', 'uig' ), 'view_item' => __( 'View Category', 'uig' ), 'search_items' => __( 'Search Categories', 'uig' ), 'not_found' => __( 'No Category found', 'uig' ), 'not_found_in_trash' => __( 'No Category found in Trash', 'uig' ), ); $args = array( 'labels' => $labels, 'singular_label' => __('Category', 'uig'), 'public' => true, 'show_ui' => true, 'hierarchical' => true, 'show_tagcloud' => false, 'show_in_nav_menus' => true, 'rewrite' => array('slug' => 'image-categories'), ); register_taxonomy('uig_image_category', 'uig_image', $args); // set up the image Tags $labels = array( 'name' => _x( 'Tags', 'taxonomy general name' ), 'singular_name' => _x( 'Tag', 'taxonomy singular name' ), 'add_new' => _x( 'Add New Tag', 'Tag'), 'add_new_item' => __( 'Add New Tag', 'uig' ), 'edit_item' => __( 'Edit Tag', 'uig' ), 'new_item' => __( 'New Tag', 'uig' ), 'view_item' => __( 'View Tag', 'uig' ), 'search_items' => __( 'Search Tags', 'uig' ), 'not_found' => __( 'No Tags found', 'uig' ), 'not_found_in_trash' => __( 'No Tags found in Trash', 'uig' ), ); $args = array( 'labels' => $labels, 'singular_label' => __('Tag', 'uig'), 'public' => true, 'show_ui' => true, 'hierarchical' => true, 'show_tagcloud' => false, 'show_in_nav_menus' => true, 'rewrite' => array('slug' => 'image-tags'), ); register_taxonomy('uig_image_tag', 'uig_image', $args); } add_action('init', 'uig_register_image_taxonomies'); |
We have two taxonomies: one for the hierarchical categories, and one for the non-hierarchical tags. These will be used to sort and filter images in the gallery.
Go to your dashboard now and you should see the “Images” post type in the menu, and also “Categories” and “Tags” underneath it.
This wraps up part one of this series. In part two we will look at setting up image sizes and the image upload form.
Hi Pippin!
Thanx for the new tutorial and sample plugin – as always, rocks!! 🙂
One suggestion I have: Please add the textdomain on all Gettext strings – that’s neccessary for actually displaying translation and will users teach even more how to properly use all this localizing stuff.
Just like so:
'not_found' => __( 'No Images found', 'uig' ),
So you have to had
, 'uig'
everywhere within Gettext.I would still prefer to use the full plugin title for shorter plugin names so it would be “user-image-gallery” if it were mine 😉
I have made myself a rule: for 3-words-names i use the full plugin name as textdomain and for longer names I try to find suitable abbreviations…
You could also add the following in your plugin headers for full awesomeness – also fits the full new WordPress standards & coding guidelines:
Text Domain: uig
Domain Path: /languages/
This way the plugin header itself (name, description, author, link, version) becomes automatically translateable and could be perfectly read by translation plugins like “Codestyling Localization” ( http://wordpress.org/extend/plugins/codestyling-localization/ ) or the WordPress.org .pot file creator.
Thanx, Dave 🙂
Ah, absolutely correct about the gettext strings. I’ll update it now.
I prefer to use the plugin prefix for the text domain because it keeps things simpler, but either method works fine.
I wasn’t aware of the new header info, but I’ll add that now too!.
Updated!
Thanx, Pippin! Just awesome 🙂
I’m registered for the 3-month paid account and am logged in, and I can’t see the restricted content. I made the purchase yesterday.
What’s your username? I can look up your account and confirm it is activated. PayPal has been doing maintenance the last few days so accounts were not all auto activated.
mrjotz
Joshua, sorry for the delay. I’ve fully activated your account.
Sorry for the troubles.
Hello when will my accounts premium membership be activated? Thanks
Looks like you paid with an echeck, which takes up to 5-8 days to complete, so your account will activate as soon as the payment has completed.
Hi,
I’m interested in this particular plugin. I realize last activity was 3 years ago but it doesn’t hurt to try.
Before I sign up for an account, I would like to make sure that this is exactly what I need.
This is a plugin to allow users to create their own galleries, correct?
Do they still have to go to the admin area to create said galleries, or can we use an extension to allow them to create galleries from the frontend? Will it be possible to display each user’s gallery, say, in their profiles?
Thanks.
There’s just a single gallery that all images are submitted to. The image submission happens from the frontend. Displaying galleries on user profiles is not part of this.
Note: this plugin is not ready for production use. This is a tutorial that shows how to build the plugin. It is expected that you then take the plugin further and adapt it to fit your exact needs.