By constant options I mean properties of the theme that don't change during every day use in production, but are changeable by the developer primarily for reusability purposes. Things like custom posts, sidebars, forms, custom features, etc.
There's really two ways that I see as viable and both of them are used in WordPress core and base themes. Edit: added a third way
Arguments inside functions
This is the way that I've been using for custom posts and such, and also the method WordPress uses for defining defaults for functions that take arguments, like wp_login_form()
or wp_nav_menu()
. It's either a variable defined inside the function being hooked or the values defined right inside the function call.
add_action( 'init', 'register_my_post_type' );
function register_my_post_type() {
$labels = array(
'name' => __( 'my_post_type' ),
'singular_name' => __( 'My Post Type' ),
...
);
$args = array(
'labels' => $labels,
'public' => true,
...
);
register_post_type( 'my_post_type', $args );
}
Globals
The register_{anything}
works by adding an instance to the global scope. For instance
function register_post_type( $post_type, $args = array() ) {
global $wp_post_types;
...
// validation
$post_type_object = new WP_Post_Type( $post_type, $args );
...
$wp_post_types[ $post_type ] = $post_type_object;
Constants
The most obvious example of this is the settings in wp-config.php
. WordPress uses these for mostly small and really basic definitions, such as the database configuration credentials and things like
define( 'ABSPATH', __DIR__ . '/' );
or define( 'WPINC', 'wp-includes' );
.
PHP supports defining arrays as constants since 5.6, so it could be possible to define these arguments. I think it would be nice if many of these options could be set in a separate file for simplicity.
Other methods, such as static variables or singleton classes seem inefficient, so they're off the table, but I'm not sure about constants.
So, would using constants like
define( 'MY_OPTION1', array(
'key' => 'value'
...
));
then using them like
add_action('init', 'my_function');
function my_function() {
some_function_that_takes_args( MY_OPTION1 );
...
}
be a bad idea? If yes, what is the correct/better way?
I have an impression that using constants might be a bad idea, though I'm not sure why or how bad. So what are some considerations in performance, usability, anomalies or other coding principles to consider?
By constant options I mean properties of the theme that don't change during every day use in production, but are changeable by the developer primarily for reusability purposes. Things like custom posts, sidebars, forms, custom features, etc.
There's really two ways that I see as viable and both of them are used in WordPress core and base themes. Edit: added a third way
Arguments inside functions
This is the way that I've been using for custom posts and such, and also the method WordPress uses for defining defaults for functions that take arguments, like wp_login_form()
or wp_nav_menu()
. It's either a variable defined inside the function being hooked or the values defined right inside the function call.
add_action( 'init', 'register_my_post_type' );
function register_my_post_type() {
$labels = array(
'name' => __( 'my_post_type' ),
'singular_name' => __( 'My Post Type' ),
...
);
$args = array(
'labels' => $labels,
'public' => true,
...
);
register_post_type( 'my_post_type', $args );
}
Globals
The register_{anything}
works by adding an instance to the global scope. For instance
function register_post_type( $post_type, $args = array() ) {
global $wp_post_types;
...
// validation
$post_type_object = new WP_Post_Type( $post_type, $args );
...
$wp_post_types[ $post_type ] = $post_type_object;
Constants
The most obvious example of this is the settings in wp-config.php
. WordPress uses these for mostly small and really basic definitions, such as the database configuration credentials and things like
define( 'ABSPATH', __DIR__ . '/' );
or define( 'WPINC', 'wp-includes' );
.
PHP supports defining arrays as constants since 5.6, so it could be possible to define these arguments. I think it would be nice if many of these options could be set in a separate file for simplicity.
Other methods, such as static variables or singleton classes seem inefficient, so they're off the table, but I'm not sure about constants.
So, would using constants like
define( 'MY_OPTION1', array(
'key' => 'value'
...
));
then using them like
add_action('init', 'my_function');
function my_function() {
some_function_that_takes_args( MY_OPTION1 );
...
}
be a bad idea? If yes, what is the correct/better way?
I have an impression that using constants might be a bad idea, though I'm not sure why or how bad. So what are some considerations in performance, usability, anomalies or other coding principles to consider?
Share Improve this question edited Mar 2, 2022 at 10:43 zoltankundi asked Jan 30, 2022 at 1:46 zoltankundizoltankundi 1931 silver badge11 bronze badges2 Answers
Reset to default 1Generally you should try to keep the amount of global variables/constants to a minimum. The third (constant) option might be a good idea if you don't have too many options, but it can get messy with time as you add more and more options.
What I usually do, is scope the constant to the corresponding classes as const
or methods returning the settings values. For example, if I have a custom post type called Book, I would create a class that takes care of all the related functionality, such as registering the post type. Additionally all theme classes can be namespaced to avoid class name collisions, but I'll show the example without namespacing for simplicity:
class BookPost{
const POST_TYPE = 'book';
public static function register(){
register_post_type(self::POST_TYPE, array('labels' => self::get_labels()));
}
public static function get_labels(){
return array(
'name' => __('Book', 'MyTheme'),
//...
);
}
}
Then you can call register from outside or inside of the class without worrying about the parameters, for example:
add_action( 'init', 'BookPost::register' );
and if you need to access the post type (or other args) from anywhere else in the code, you can just use:
BookPost::POST_TYPE;
BookPost::get_labels();
There are a couple of things to mention here:
- Since you can't use expressions (such as calling the
__()
method) in constants, you will have to use methods for retrieving the more dynamic values like label. - Here I'm using static methods because this particular example doesn't require storing state, and also it's easier to call the methods statically. But of course, based on your requirements you might prefer instantiating an object and using standard non-static methods.
I'm not saying that this is the best approach, but this is what I usually do and it's been working well for me. The additional advantage is that you can add more helper methods to this class as your code grows and you won't need to worry about passing the post type, etc. For example, you can have something like:
BookPost::get_latest();
BookPost::get_all();
BookPost::get_by_genre();
Also in terms of performance, registering a constant in a class vs using an array constant with options shouldn't make any meaningful difference in scenarios like this one.
You should look at wordpress options page:
https://codex.wordpress.org/Creating_Options_Pages
That page will give you a good starting point to make options and settings for WordPres.