Carbon Fields is a WordPress library for creating and managing custom fields using a simple API. It allows developers to easily add fields to posts, taxonomies, users, comments, and widgets. It supports Gutenberg blocks and repeating fields.
Carbon Fields is free, open-source, compatible with PHP 5.3+, and suitable for commercial projects. It also supports metafields and dynamic interfaces for enhanced functionality.
If you develop themes using OOP and automatic class loading, you’ll find Carbon Fields easy to work with. It can be installed with Composer.
Pros of Carbon Fields:
- There is no admin panel interface for field creation, meaning fields are only created via code, reducing the chance for clients to rename fields and break the code accidentally.
- A large variety of pre-built field types.
- Flexibility to extend and create custom fields.
- Excellent documentation with examples.
- Free, open-source, and usable in any commercial project.
- It supports older PHP versions and is fully compatible with PHP 8.3.
Cons of Carbon Fields:
- Requires knowledge of OOP for field implementation.
- Installed via composer, which some developers may not be familiar with. (If you need help, read this article on how to use composer in your theme or plugin.)
- The incomplete interface for Gutenberg blocks only shows fields without a visual preview like ACF PRO.
Step-by-step Code for Connecting Carbon Fields
We will start by initializing the composer in the theme directory by running the composer init command and answering a few questions.
After that, the vendor
folder and the composer.json file should be created. Next, install Carbon Fields by running:
composer require htmlburger/carbon-fields
Add the following code in the functions.php file to load the main library file:
<?php
/**
* Connect library startup file
*
* @return void
*/
function crb_load() {
require_once('vendor/autoload.php');
\Carbon_Fields\Carbon_Fields::boot();
}
add_action('after_setup_theme', 'crb_load');
Code to Create a Gutenberg Block in Carbon Fields
<?php
/**
* Add Block FAQ.
*/
function crb_add_gutenberg_block() {
// FAQ block.
Block::make(
__( 'FAQ', 'iwpdev' )
)->add_fields(
[
Field::make(
'complex',
'faq_items',
__( 'FAQs', 'iwpdev' )
)->add_fields(
[
Field::make( 'text', 'title', __( 'Title', 'iwpdev' ) ),
Field::make( 'rich_text', 'description', __( 'Description', 'iwpdev' ) ),
]
),
]
)->set_category(
'iwpdev',
'editor-code'
)->set_render_callback(
function ( $fields, $attributes, $inner_blocks ) {
get_template_part(
'template-parts/blocks/faq',
'block',
[
'attributes' => $attributes,
'fields' => $fields,
]
);
}
);
}
add_action( 'carbon_fields_register_fields', 'crb_add_gutenberg_block' );
Code for Enqueuing Bootstrap 5 Styles and Scripts
<?php
/**
* Add Bootstrap 5
*
* @return void
*/
function add_bootstrap() {
wp_enqueue_style('iwp_bootstrap', '//cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css', [], '5.2.3');
wp_enqueue_script('iwp_bootstrap', '//cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js', ['jquery'], '5.2.3', true);
}
add_action('wp_enqueue_scripts', 'add_bootstrap');
Block Template Code
<?php
$fields = $args['fields'];
$attributes = $args['attributes'];
if ( ! empty( $fields['faq_items'] ) ) {
?>
<div class="accordion" id="accordionPanelsStayOpenExample">
<?php foreach ( $fields['faq_items'] as $key => $item ) { ?>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
aria-expanded="false"
data-bs-target="#<?php echo esc_html( 'accord-' . $key ); ?>">
<?php echo esc_html( $item['title'] ?? '' ); ?>
</button>
</h2>
<div id="<?php echo esc_html( 'accord-' . $key ); ?>" class="accordion-collapse collapse"
aria-labelledby="panelsStayOpen-headingOne">
<div class="accordion-body">
<?php echo wp_kses_post( wpautop( $item['description'] ?? '' ) ); ?>
</div>
</div>
</div>
<?php } ?>
</div>
<?php
}
At this point, our Gutenberg block should appear as shown in the screenshots.
Results We Obtained:
- Page Generation Time: 0.2100s
- Peak Memory Usage: 6.7 MB
- Database Queries: 32
- Database Queries Time: 0.0104s
- Number of Scripts Loaded: 10
- Number of Styles Loaded: 24
/**
* FAQ register block.
*
* @return void
*/
function register_gutenberg_blocks() {
if (function_exists('acf_register_block')) {
acf_register_block_type([
'name' => 'FAQ',
'title' => __('FAQ', 'iwpdev'),
'description' => __('FAQ', 'iwpdev'),
'category' => 'acf-blocks',
'post_types' => ['page'],
'supports' => ['anchor' => true, 'align' => ['full', 'wide'], 'jsx' => true],
'render_template' => 'template-parts/block/faq.php',
]);
}
}
add_action('acf/init', 'register_gutenberg_blocks');
We create the block in the admin panel using one repeater field with two subfields: one for the title and the other for the content.
Don’t forget to select the template rendering option for this block, which was registered in the code above.
If everything is done correctly, you should see this block appear as shown in the screenshots.
Block Template Code
<?php
$faq_arg = get_field('faq');
if (!empty($faq_arg)) { ?>
<div class="accordion" id="accordionPanelsStayOpenExample">
<?php foreach ($faq_arg as $key => $item) { ?>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#<?php echo esc_html('accord-' . $key); ?>">
<?php echo esc_html($item['title'] ?? ''); ?>
</button>
</h2>
<div id="<?php echo esc_html('accord-' . $key); ?>" class="accordion-collapse collapse" aria-labelledby="panelsStayOpen-headingOne">
<div class="accordion-body">
<?php echo wp_kses_post(wpautop($item['description'] ?? '')); ?>
</div>
</div>
</div>
<?php } ?>
</div>
<?php }
Results We Obtained with ACF PRO:
- Page Generation Time: 0.4336s
- Peak Memory Usage: 8.1 MB
- Database Queries: 38
- Database Queries Time: 0.0109s
- Number of Scripts Loaded: 8
- Number of Styles Loaded: 24
Parameter name | ACF | Carbone Fields |
Page Generation Time | – | + |
Peak Memory Usage | – | + |
Database Queries | – | + |
Database Queries Time | – | + |
Number of Scripts Loaded | + | – |
Number of Styles Loaded | + | + |
Speed of field creation | + | – |
Conclusion and Full Comparison
Carbon Fields is faster and more lightweight, especially if your theme contains many custom blocks, which provides a small boost in speed. It works reliably on both older and newer versions of PHP. Clients cannot change field parameters, ensuring the stability of your code, which is crucial for large projects.
ACF is an excellent solution for quickly creating blocks and implementing them without much coding knowledge. However, the downside is the cost and longer block generation times on the front end.
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
Step 1: Create the patterns
Directory in Your Theme
Create the patterns
Directory: In the root directory of your theme, create a folder named patterns
if it doesn’t already exist. This folder will hold all your patterns.
Step 2: Create Patterns for Different Content Types
Create pattern files in the patterns
directory for various content types.
Pattern for Pages (page-pattern.php
):
<?php
/**
* Title: Page Hero Section
* Slug: mytheme/page-hero
* Categories: hero
* Keywords: hero, page
* Block Types: core/post-content
* Post Types: page
* Viewport width: 1400
*/
?>
<!-- wp:cover {"url":"<?php echo esc_url( get_template_directory_uri() ); ?>/images/hero-bg.jpg","dimRatio":50} -->
<div class="wp-block-cover">
<span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span>
<img class="wp-block-cover__image-background" alt="Hero Background Image" src="<?php echo esc_url( get_template_directory_uri() ); ?>/images/hero-bg.jpg"/>
<div class="wp-block-cover__inner-container">
<!-- wp:heading {"align":"center"} -->
<h2 class="has-text-align-center">Welcome to Our Website</h2>
<!-- /wp:heading -->
<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Here’s a brief description of what we do.</p>
<!-- /wp:paragraph -->
</div>
</div>
<!-- /wp:cover -->
Pattern for Posts (post-pattern.php
):
<?php
/**
* Title: Blog Post Layout
* Slug: mytheme/post-layout
* Categories: blog
* Keywords: post, layout, blog
* Block Types: core/post-content
* Post Types: post
* Viewport width: 1400
*/
?>
<!-- wp:columns -->
<div class="wp-block-columns">
<!-- wp:column {"width":"70%"} -->
<div class="wp-block-column" style="flex-basis:70%">
<!-- wp:heading -->
<h2>Blog Post Title</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Start writing your blog post here...</p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
<!-- wp:column {"width":"30%"} -->
<div class="wp-block-column" style="flex-basis:30%">
<!-- wp:paragraph -->
<p>Sidebar content goes here.</p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
Pattern for Custom Post Type (portfolio-pattern.php
):
<?php
/**
* Title: Portfolio Item Layout
* Slug: mytheme/portfolio-layout
* Categories: portfolio
* Keywords: portfolio, project
* Block Types: core/post-content
* Post Types: portfolio
* Viewport width: 1400
*/
?>
<!-- wp:heading -->
<h2>Project Title</h2>
<!-- /wp:heading -->
<!-- wp:image -->
<figure class="wp-block-image"><img src="<?php echo esc_url( get_template_directory_uri() ); ?>/images/project-image.jpg" alt="Project Image"/></figure>
<!-- /wp:image -->
<!-- wp:paragraph -->
<p>Project description goes here...</p>
<!-- /wp:paragraph -->
Step 3: Verify the Patterns
After adding patterns to the patterns
directory, WordPress will automatically register them. To check:
Create a New Page or Post:
- Go to the WordPress admin panel and create a new page, post, or custom post type (e.g., “Portfolio”).
- WordPress will automatically display a modal window to select from the available patterns if they are registered for the current post type.
Conclusion
WordPress simplifies working with patterns by automatically registering them and showing a pattern selection modal when creating new content. You only need to properly format and place patterns in the patterns
directory of your theme. This feature speeds up content creation by providing users with predefined templates for various scenarios.
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
In this article, we will add the output of our car and all the fields we created in the last article.
Connecting scripts
Let’s start by creating the assets folder at the root of our project and copying there all the files that came to us with the layout
Now you need to add a hook to connect scripts and styles to the Main.php file in the init function
add_action( 'wp_enqueue_scripts', [ $this, 'add_scripts' ] );
Create this function
public function add_scripts(): void {
wp_enqueue_script( 'ecl_build', ECL_URL . '/assets/js/build.js', [ 'jquery' ], ECL_VERSION, true );
wp_enqueue_script( 'html5shiv', '//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js', [], '3.7.0', false );
wp_enqueue_script( 'respond', '//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js', [], '1.4.2', false );
wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );
wp_script_add_data( 'respond', 'conditional', 'lt IE 9' );
wp_enqueue_style( 'ecl_main', ECL_URL . '/assets/css/main.css', '', ECL_VERSION );
$global_style = ':root{ --color-one:#f26b36; --color-two:#be542a;}';
wp_add_inline_style( 'ecl_main', $global_style );
}
wp_enqueue_script – Enqueues a script
wp_script_add_data – Adds conditions when including a script
wp_enqueue_style – Enqueue styles
wp_add_inline_style – Displays inline styles in the header
Create an output template override filter
Go to the file AddCPT.php and add a filter to the init function
add_filter( 'template_include', [ $this, 'add_single_car_page' ] );
Create a function and add conditions to override the template
/**
* Add single car template.
*
* @param string $template
*
* @return string
*/
public function add_single_car_page( string $template ): string {
if ( is_singular( 'cars' ) && ! locate_template( [ 'single-cars.php' ] ) ) {
return ECL_PATH . '/template/single-cars.php';
}
return $template;
}
The condition we are checking is a car page and there is a single-cars.php template in the theme being used.
If there is no template, then it will be displayed from the template folder from the root folder of our plugin.
is_singular – Checks if the post page is being viewed
locate_template – Finds the best server path to the specified template file. The search takes into account the child theme.
Connecting layout
We create a template folder at the root of our plugin and in it the single-cars.php file
We copy our layout there, we can find it at the link: https://drive.google.com/file/d/1dF94sQjEREAOG3jLGMr3OqX4wSCwMc6n/view?usp=share_link
Full file code at the link https://gitlab.com/AlsconWeb/ease-car-listing/-/blob/16d71d9a5677e4944619b3069aac5f8ffde98320/template/single-cars.php
carbon_get_the_post_meta(“The name of the field we want to get”) – Used in the standard loop
If we want to get this field in a non-loop then we need to use
carbon_get_post_meta(“The ID of the post the field is bound to”, “The name of the field we want to get”)
numfmt_create — Creates a number formatter
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
In this article, we’ll look at how to create a Custom Post Type, Custom Taxonomy, and fields for the Auto page.
Creating a Custom Post Type
Open the file AddCPT.php
The first thing we need to add to the init function
add_action( 'init', [ $this, 'register_post_auto' ] );
The first parameter is responsible for when our function will be called. Next, we need to pass an array of parameters, the first of which is $this is an instance of our class that indicates where to look for our function, followed by the name of the function.
Now we need to create a function that will register our new Auto post type. To do this, we need to call the register_post_type function and pass the following parameters to it
Here is our function code:
/**
* Register CPT Auto.
*
* @return void
*/
public function register_post_auto(): void {
register_post_type(
'cars',
[
'label' => null,
'labels' => [
'name' => __( 'Cars', 'ease-car-listing' ),
'singular_name' => __( 'Car', 'ease-car-listing' ),
'add_new' => __( 'Add car', 'ease-car-listing' ),
'add_new_item' => __( 'Adding a car', 'ease-car-listing' ),
'edit_item' => __( 'Car editing', 'ease-car-listing' ),
'new_item' => __( 'New car', 'ease-car-listing' ),
'view_item' => __( 'View car', 'ease-car-listing' ),
'search_items' => __( 'Search car', 'ease-car-listing' ),
'not_found' => __( 'Not found', 'ease-car-listing' ),
'not_found_in_trash' => __( 'Not found in cart', 'ease-car-listing' ),
'menu_name' => __( 'Cars', 'ease-car-listing' ),
],
'description' => '',
'public' => true,
'show_in_rest' => null,
'rest_base' => null,
'menu_position' => 30,
'menu_icon' => 'dashicons-car',
'hierarchical' => false,
'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'revisions' ],
'taxonomies' => [ 'cars' ],
'has_archive' => true,
'rewrite' => true,
'query_var' => true,
]
);
}
What parameters should you pay attention to?
menu_position – will allow us to change the position in the WordPress menu
menu_icon – Displays an icon
supports – The options we need [ ‘title’, ‘editor’, ‘thumbnail’, ‘excerpt’, ‘custom-fields’, ‘revisions’ ]
Creation of Custom Taxonomy
Adding another Action to the init function
add_action( 'init', [ $this, 'register_tax_mark' ] );
Everything is the same as with creating a new post type.
We create a function and call the function and call register_taxonomy in it and pass parameters to it
/**
* Register taxonomy mark & models.
*
* @return void
*/
public function register_tax_mark(): void {
register_taxonomy(
'mark',
[ 'cars' ],
[
'label' => '',
'labels' => [
'name' => __( 'Marks & Models', 'ease-car-listing' ),
'singular_name' => __( 'Marks & Models', 'ease-car-listing' ),
'search_items' => __( 'Search Mark', 'ease-car-listing' ),
'all_items' => __( 'All Marks & Models', 'ease-car-listing' ),
'view_item ' => __( 'View Marks', 'ease-car-listing' ),
'parent_item' => __( 'Marks', 'ease-car-listing' ),
'parent_item_colon' => __( 'Models', 'ease-car-listing' ),
'edit_item' => __( 'Edit Marks & Models', 'ease-car-listing' ),
'update_item' => __( 'Update Marks & Models', 'ease-car-listing' ),
'add_new_item' => __( 'Add New', 'ease-car-listing' ),
'new_item_name' => __( 'New Marks & Models', 'ease-car-listing' ),
'menu_name' => __( 'Marks & Models', 'ease-car-listing' ),
'back_to_items' => __( '← Back to Marks & Models', 'ease-car-listing' ),
],
'description' => __( 'The main category is the brand of the car, the child category will be the model.', 'ease-car-listing' ),
'public' => true,
'hierarchical' => true,
'rewrite' => true,
'capabilities' => [],
'show_admin_column' => true,
] );
}
We also need to add another taxonomy for engine size, for this, I register another function so it will be easier to disable or edit taxonomies in the future. And so we do everything by analogy
/**
* Register taxonomy engine.
*
* @return void
*/
public function register_tax_engine(): void {
register_taxonomy(
'engine',
[ 'cars' ],
[
'label' => '',
'labels' => [
'name' => __( 'Engine', 'ease-car-listing' ),
'singular_name' => __( 'Engine', 'ease-car-listing' ),
'search_items' => __( 'Search Engine', 'ease-car-listing' ),
'all_items' => __( 'All Engine', 'ease-car-listing' ),
'view_item ' => __( 'View Engine', 'ease-car-listing' ),
'parent_item' => __( 'Parens Engine', 'ease-car-listing' ),
'parent_item_colon' => __( 'Parent', 'ease-car-listing' ),
'edit_item' => __( 'Edit Engine', 'ease-car-listing' ),
'update_item' => __( 'Update Engine', 'ease-car-listing' ),
'add_new_item' => __( 'Add New', 'ease-car-listing' ),
'new_item_name' => __( 'New Engine', 'ease-car-listing' ),
'menu_name' => __( 'Engine', 'ease-car-listing' ),
'back_to_items' => __( '← Back to Engine', 'ease-car-listing' ),
],
'description' => '',
'public' => true,
'hierarchical' => true,
'rewrite' => true,
'capabilities' => [],
'show_admin_column' => true,
] );
}
Here is the complete code of our file https://gitlab.com/AlsconWeb/ease-car-listing/-/blob/25ed13774bf667a8cb553a947be13cda08a403c7/src/php/CPT/AddCPT.php
Creating fields for our auto post type
We move on to the CarboneFields.php file
First of all, we need to initialize the main Carbone Fields class so that it loads all of its classes.
Add action to the init function
add_action( 'after_setup_theme', [ $this, 'carbon_fields_init' ] );
We need to run this function on the after_setup_theme hook and all we need to do in this function is to run the static Boot function
Carbon_Fields::boot();
code of our function
/**
* Carbone field init.
*
* @return void
*/
public function carbon_fields_init(): void {
Carbon_Fields::boot();
}
Now we can add the fields themselves, for this, we need action from carbon fields
carbon_fields_register_fields
add_action( 'carbon_fields_register_fields', [ $this, 'add_carbone_fields_to_cars' ] );
We create this function and start creating fields.
To create the fields first of all we need to create a container like this.
Container::make( 'post_meta', __( 'Vehicle parameters', 'ease-car-listing' ) )
The first parameter specifies the type of container the second parameter is its name
Next, we need to specify where to display these fields, for this, we need to use the where function where the first parameter can be post_format, post_id, post_level, post_parent_id, post_ancestor_id, post_template, post_term, post_type
The second parameter is responsible for how to compare parameters and can take the value ‘=’, ‘!=’, ‘>’, ‘>=’, ‘<‘, ‘<=’, ‘IN’, ‘NOT IN’, ‘CUSTOM ‘ You can read more about these options in the documentation for CarboneFields.
In our case, we will use the post_type and give our title to our post.
->where( 'post_type', '=', 'cars' )
I will use tabs to separate the different types of fields so I will use the add_tab function which has 2 parameters. The first is the name of the tab that is displayed on the front and the second parameter is an array of carbon fields.
So, the complete code for this function came out like this. If you have any questions, you can always ask a question in the comments below the video.
/**
* Add Carbon fields to CPT cars
*
* @return void
*/
public function add_carbone_fields_to_cars(): void {
Container::make( 'post_meta', __( 'Vehicle parameters', 'ease-car-listing' ) )
->where( 'post_type', '=', 'cars' )
->add_tab(
__( 'General', 'ease-car-listing' ),
[
Field::make( 'text', 'ecl_vin', __( 'Vin number', 'ease-car-listing' ) )->set_width( 50 ),
Field::make( 'text', 'ecl_stock_number', __( 'Stock number', 'ease-car-listing' ) )
->set_width( 50 ),
Field::make( 'text', 'ecl_car_mileage', __( 'Сar mileage', 'ease-car-listing' ) )
->set_width( 50 ),
Field::make( 'select', 'ecl_body_type', __( 'Body type', 'ease-car-listing' ) )
->add_options(
[
'compact' => __( 'Compact', 'ease-car-listing' ),
'sedan' => __( 'Sedan', 'ease-car-listing' ),
'coupe' => __( 'Coupe', 'ease-car-listing' ),
'hatchback' => __( 'Hatchback', 'ease-car-listing' ),
'kombi' => __( 'Kombi', 'ease-car-listing' ),
'limousine' => __( 'Limousine', 'ease-car-listing' ),
'microvan' => __( 'Microvan', 'ease-car-listing' ),
'minivan' => __( 'Minivan', 'ease-car-listing' ),
'pickup' => __( 'Pickup', 'ease-car-listing' ),
'roadster' => __( 'Roadster', 'ease-car-listing' ),
'suv' => __( 'SUV', 'ease-car-listing' ),
'wagon' => __( 'Wagon', 'ease-car-listing' ),
'pickup_track' => __( 'Pickup track', 'ease-car-listing' ),
'van' => __( 'Van', 'ease-car-listing' ),
]
)->set_width( 50 ),
Field::make( 'select', 'ecl_fuel_type', __( 'Fuel type', 'ease-car-listing' ) )
->add_options(
[
'gas' => __( 'Gas', 'ease-car-listing' ),
'diesel' => __( 'Diesel', 'ease-car-listing' ),
'electric' => __( 'Electric', 'ease-car-listing' ),
]
)->set_width( 50 ),
Field::make( 'text', 'ecl_car_year', __( 'Vehicle year', 'ease-car-listing' ) )
->set_width( 50 ),
Field::make( 'text', 'ecl_horsepower', __( 'Vehicle Horsepower', 'ease-car-listing' ) )
->set_width( 50 )
->set_attribute( 'type', 'number' ),
Field::make( 'text', 'ecl_body_color', __( 'Body color', 'ease-car-listing' ) )
->set_width( 50 ),
Field::make( 'text', 'ecl_interior_color', __( 'Interior color', 'ease-car-listing' ) )
->set_width( 50 ),
Field::make( 'text', 'ecl_number_of_airbags', __( 'Number of airbags', 'ease-car-listing' ) )
->set_width( 50 )
->set_attribute( 'type', 'number' ),
Field::make( 'text', 'ecl_number_of_seats', __( 'Number of seats', 'ease-car-listing' ) )
->set_width( 50 )
->set_attribute( 'type', 'number' ),
Field::make( 'text', 'ecl_number_of_doors', __( 'Number of doors', 'ease-car-listing' ) )
->set_width( 50 )
->set_attribute( 'type', 'number' ),
]
)
->add_tab(
__( 'Additional Information', 'ease-car-listing' ),
[
Field::make( 'rich_text', 'ecl_additional_info', __( 'Additional Information', 'ease-car-listing' ) ),
]
)
->add_tab(
__( 'Gallery', 'ease-car-listing' ),
[
Field::make( 'media_gallery', 'ecl_gallery', __( 'Gallery', 'ease-car-listing' ) )
->set_type(
[
'image',
'video',
]
),
]
)
->add_tab(
__( 'Price', 'ease-car-listing' ),
[
Field::make( 'text', 'ecl_price', __( 'Price', 'ease-car-listing' ) )->set_width( 30 ),
Field::make( 'text', 'ecl_sales_price', __( 'Sales price', 'ease-car-listing' ) )
->set_width( 30 ),
Field::make( 'text', 'ecl_by_month', __( 'Price per month', 'ease-car-listing' ) )
->set_width( 30 ),
]
);
}
You can always find the code of the entire file here: https://gitlab.com/AlsconWeb/ease-car-listing/-/commit/ee77a1cb22d2135f5bbeccdf26f9d37fb934b7c0#9ef8bcfcbdaab0d19e056f80ce0cc3d3c362c61f
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
Good afternoon, today I started my YouTube channel and a series of videos on creating a plugin for WordPress.
What will our plugin do in the future?
It will create an opportunity to turn your site into an entire car dealership.
The first video is about how I set up the Development Environment.
So, let’s begin!
The first thing we need to go to the site https://www.docker.com/ download and install it on your computer.
For the next step, we need to globally install Composer, we need it to automatically import our future classes according to the PSR-4 standard (you can read about this standard here https://www.php-fig.org/psr/psr-4/ ).
To download and install Composer, follow the instructions on the official website https://getcomposer.org/doc/00-intro.md, we need a global installation.
And so the next step we need to clone the Docker image repository https://github.com/wodby/docker4wordpress
You may have problems with it because it refused to work for me on Mac OS so I had to change it a little if you are facing the same problem clone my version from this link https://gitlab.com/AlsconWeb/wordpress-dev- environment-docker
And so all the preparations for the start are over and we can start!
Go to the project folder in my case it is car-listing and copies the following files there from the repository above
- .env
- docker.mk
- docker-compose.yml
- Makefile
- docker
Now we need to set up .env
To do this, we need to change the following parameters
PROJECT_NAME - responsible for the name of the project in docker
PROJECT_BASE_URL - Url where our site will be available in my case carlisting.docker.localhost
DB_NAME - the name of the created database (I make it by the name of the project)
DB_USER - database username (I make it by project name)
DB_PASSWORD - database password (I make it by project name)
I also change the PHP version from the default 7.4 to 8.0
PHP_TAG=8.0-dev-macos-4.22.2
Now we need to go to this folder and execute the make command and wait until the command is executed all the images will affect and connect
Next, we need to download WP for this, we just need to execute the make wp core download command – this is the standard wp-cli command, but we need to execute it with the make command so that the docker understands that it needs to install the image.
We execute and wait for the command to be executed.
The next step we need to go to the app folder and change the filename wp-config-sampel.php to wp-config.php
Open it for editing
And set the database accesses that you configured in the .env file
The main point in the need to change
define( 'DB_HOST', 'localhost' );
to
define( 'DB_HOST', 'mariadb' );
‘mariadb’ is the name of the docker container.
Next, we generate keys for the site https://api.wordpress.org/secret-key/1.1/salt/
paste them further standard WordPress installation
The next step is to create our plugin folder in /wp-content/plugins folder, I named it ease-car-listing.
Composer settings
And so now we need to initialize composer for this we execute the composer init command and answer or skip all the questions that he asks us.
As a result of executing this command, we should have a composer.json file
Open it for editing and add the required information
"description": "Ease car listing for your site",
"license": "GPL-2.0-only",
Add a description and type of license
"homepage": "https://i-wp-dev.com/", //package homepage
"type": "wordpress-plugin", // package type (if it's a plugin) or wordpress-theme if it's a theme
support: {
"issues": https://i-wp-dev.com/ // url where you can leave comments
},
"prefer-stable": true,
"config": {
// tells composer which PHP version to run dependencies and project on
platform: {
"php": "7.4"
}
},
The main block for automatically loading our project’s classes
"autoload": {
"psr-4": {
"Iwpdev\\EaseCarListing\\": "src/php" //This means that all our classes will be in the src/php folder
}
},
The minimum stable version I usually set it to dev
"minimum-stability": "dev",
Next, we have development dependencies, this is a very important block for PHP_CodeSniffer to work.
"require-dev": {
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6",
"phpcompatibility/php-compatibility": "^9.3",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"wp-coding-standards/wpcs": "^2.3",
"php-coveralls/php-coveralls": "^2.4"
}
Here is what I got the complete composer.json code
{
"name": "iwpdev/ease-car-listing",
"description": "Ease car listing for your site",
"license": "GPL-2.0-only",
"keywords": [
"ease",
"car",
"listing",
"car listing",
"ease car listing",
"ukrane product"
],
"homepage": "https://i-wp-dev.com/",
"type": "wordpress-plugin",
"support": {
"issues": "https://i-wp-dev.com/"
},
"prefer-stable": true,
"config": {
"platform": {
"php": "7.4"
}
},
"autoload": {
"psr-4": {
"Iwpdev\\EaseCarListing\\": "src/php"
}
},
"authors": [
{
"name": "iwpdev",
"email": "
iw****@ou*****.com
"
}
],
"minimum-stability": "dev",
"require": {
"htmlburger/carbon-fields": "^3.3"
},
"require-dev": {
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6",
"phpcompatibility/php-compatibility": "^9.3",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"wp-coding-standards/wpcs": "^2.3",
"php-coveralls/php-coveralls": "^2.4"
}
}
Add dependency data and execute composer update command.
Setting up PHP Storm
Next, we go to the PHP_CodeSniffer settings, open the PHP Storm settings, go to Preferences | PHP | Quality Tools open PHP_CodeSniffer click on the ellipsis in the PHP_CodeSniffer path settings we must add a file that is located /vendor/bin/phpcs (in the case of Windows it will be a file with a bat extension)
We click on the validate button and we should get the result on my screen
If you see a similar result we can move on to the next step.
Now we need to add a file that will be responsible for autocorrection.
It is located a little lower in the Path to phpcbf field and we select this file in the same cape
We save and return to the settings now we need to select the standard code.
I use a custom one that my friend gave me and this standard is used in many large studios that develop WordPress
In the Coding standard, I choose custom and I specify the path to this file, which I copied to the root of the plugin in advance. You can find this file at this link https://codeshare.io/oQYERp this field we just save the settings.
And so we got to the code itself.
Main plugin file
I created the main plugin file where the plugin itself will be initialized
He looks like this
<?php
/**
* Ease Car Listing.
*
* @package iwpdev/ease-car-listing
* @author Alex Lavyhin
* @license GPL-2.0-or-later
* @wordpress-plugin
*
* Plugin Name: Ease Car Listing.
* Plugin URI: https://i-wp-dev.com
* Description: Ease car listing for your site
* Version: 1.0.0
* Author: ALex Lavyhin
* Author URI: https://i-wp-dev.com
* License: GPL2
*
* Text Domain: key-crm-synchronization
* Domain Path: /languages
*/
if ( ! defined( 'ABSPATH' ) ) {
// @codeCoverageIgnoreStart
exit;
// @codeCoverageIgnoreEnd
}
use Iwpdev\EaseCarListing\Admin\Notification\Notification;
use Iwpdev\EaseCarListing\Main;
/**
* Plugin version.
*/
const ECL_VERSION = '1.0.0';
/**
* Plugin path.
*/
const ECL_PATH = __DIR__;
/**
* Plugin main file
*/
const ECL_FILE = __FILE__;
/**
* Min ver php.
*/
const ECL_PHP_REQUIRED_VERSION = '7.4';
/**
* Plugin url.
*/
define( 'ECL_URL', untrailingslashit( plugin_dir_url( ECL_FILE ) ) );
/**
* Check php version.
*
* @return bool
* @noinspection ConstantCanBeUsedInspection
*/
function is_php_version(): bool {
if ( version_compare( constant( 'KEY_CRM_SYNCHRONIZATION_PATH' ), phpversion(), '>' ) ) {
return false;
}
return true;
}
if ( ! is_php_version() ) {
add_action( 'admin_notices', [ Notification::class, 'php_version_nope' ] );
if ( is_plugin_active( plugin_basename( constant( 'ECL_FILE' ) ) ) ) {
deactivate_plugins( plugin_basename( constant( 'ECL_FILE' ) ) );
// phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
}
return;
}
require_once ECL_FILE . '/vendor/autoload.php';
new Main();
Carbon Fields class
I also created a class for managing Carbone Fields, but this is just a blank that we will do in the next video and article
/**
* Add Custom fields in project.
*
* @package iwpdev/ease-car-listing
*/
namespace Iwpdev\EaseCarListing;
/**
* CarboneFields class file.
*/
class CarboneFields {
/**
* CarboneFields construct.
*/
public function __construct() {
$this->init();
}
/**
* Init hooks.
*
* @return void
*/
private function init(): void {
}
}
AddCPT class
And I created a blank for creating a Custom post type
/**
* Create Custom post type.
*
* @package iwpdev/ease-car-listing
*/
namespace Iwpdev\EaseCarListing\CPT;
/**
* AddCPT class file.
*/
class AddCPT {
/**
* AddCPT construct
*/
public function __construct() {
$this->init();
}
/**
* Init hooks.
*
* @return void
*/
private function init(): void {
}
}
This is what my project tree looks like now
Also, watch the video on this topic on my channel!
Thank you for reading this article to the end, I hope it has become useful for you, and subscribe to my channel soon there will be a lot of interesting things
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
When solving problems from blogging, which was the main specialization of WordPress 18 years ago, before opening a multi-vendor marketplace and deploying an ERP system, you can do without a single line of code, which does not eliminate immersion in business processes and direct implementation, but only those who understand the architecture and API of the system, it reveals its true capabilities and beauty.
And no, this is not a Devastator transformer, but it is the rich and well-thought-out API that makes WordPress a reliable basis for solving a wide variety of tasks.
Today, more than 40% of the 10 million most popular sites are powered by WordPress [1].
The WordPress.org repository has over 7,400 open source themes and 50,000 plugins, from basic sliders to alternatives to the WordPress built-in WYSIWYG block editor, as well as several powerful e-commerce solutions and a variety of add-ons.
WordPress from driver to design engineer
WordPress allows you to quickly get started and test a business idea or concept with minimal time and money. If this is an online store, then in addition to filling with goods that can be imported or synchronized with another system, it will take most of the time to decide through which payment aggregator to receive money and which online cashier to connect.
As business needs grow or tasks become more complex, the look, functionality and connections of WordPress to third-party applications can change and become more complex, without the need to switch to another platform, which reduces the cost of revision and modernization.
After installation, WordPress presents a ready-to-use dashboard, where content is divided into pages and posts editable in the Block Editor, which entered the core of WordPress in December 2018 at the first stage of the “Gutenberg” project [2], comments and media files, and the main page displays the latest news in the design of the pre-installed default theme, traditionally released annually for the last 11 years, combining minimalism and current ideas about design and UX, which is clearly visible if you look at these topics in chronological order [3].
All WordPress capabilities are exposed to developers through hooks (filters and events) [4].
Depending on the needs of the project, development can be carried out at various levels of complexity.
Assembly
Creation of a website, forum, online store or platform for other tasks without a single line of code based on ready-made free and paid themes and plugins, configuring WordPress, theme and plugins parameters through a visual interface in the control panel.
The minimum set of plugins for most sites
- Security plugin – protects against password guessing, blocks bots, etc., two-factor authentication is available in the paid version.
- SEO plugin – for writing an optimized title, description, assessing the quality of content, adding Schema.org data, setting up sitemap.xml, etc.
- Plugin for transliteration of URL and names of uploaded files.
- Plugin for converting images to webp format – significantly reduces the size of raster images and pleases Google PageSpeed.
- Plugin for spam protection if commenting is enabled for pages or posts.
- A caching plugin can be effective or not, depending on the dynamics of content updates and traffic.
CSS changes
Stylistic adjustments are implemented by additional inline styles entered in a special customizer field (Control Panel> Appearance> Customize> Additional Styles).
Customization + HTML, PHP and WordPress API and plugins
- Changing a ready-made theme or expanding its functionality by creating a child theme for a free or premium theme. With this approach, the parent theme is kept updated and minimal support is required from the child theme developer.
- Plugins that display information on the frontend have their own templates, which, in addition to modernization through hooks, can be replaced by templates in the parent or child theme folder, which allows you to make significant changes both in the content presentation and in the plugin’s logic as a whole (changes affecting the logic, it is recommended to put it in a plugin). An example plugin with its own templates and extensive API is WooCommerce, a popular WordPress eCommerce solution.
Development of JavaScript, MySQL, version control system (Git), package management system (NPM, Composer, Yarn, etc.), package building systems (Gulp, Webpack, etc.), Bash, adherence to WordPress coding standards (Coding Standards)
- Creation of your own themes with a unique design for the purpose of a specific project, for the .org repository or for sale through marketplaces.
- Creation of plugins that implement additional functionality for a specific project, for the .org repository or for sale through marketplaces.
- Transforming WordPress into an application via PWA.
React and the WordPress interface for working with it
- Development of blocks and patterns for the Block Editor or other functionality for the frontend and backend.
- Development of themes with full-site editing (a new direction and a promising niche for developers).
Other technologies, frameworks and platforms
- Integration of WordPress with third-party applications, setting up synchronization and data exchange.
- Connecting your own mobile application to WordPress.
- Using WordPress as a CMS and implementing a frontend on a framework – Gatsby, Vue.js, and others.
The REST API, which was included in the core of WordPress in 2016, in addition to interacting with third-party applications, allows you to use WordPress solely as a content management system. This technology is called Headless or Decoupled CMS. In version WordPress 5.6 in 2020, the core of the system includes “Application Passwords”, which allow applications to log in with user rights, and at the same time not use the main account password.
An alternative to the REST API is GraphQL, available with the WPGraphQL plugin.
Implementation of a WordPress project is limited by the skills of the developers, the needs and budget of the client, and allows you to get the most out of your investment. If the project can be clearly described, it can be implemented in WordPress.
Bonus level
WordPress is open source software supported by volunteers. This means that everyone can take part in the development of the system, from the error message to the proposal and direct implementation of new functionality.
To get an idea of the number of developers working on a specific WordPress release, click the Contributors tab on the About WordPress page by the logo in the left-right corner of your dashboard, or scroll down to the bottom of this page to see a list of external libraries used. The list of contributors also accompanies the release news on WordPress.org.
The future of WordPress
In July 2021, the WordPress 5.8 core will include Full Site Editing in line with Phase 2 of Project Gutenberg. FSE opens up new opportunities, while the tools familiar to users and developers and compatibility with existing themes and plugins will remain.
FSE preparation includes extensive documentation, but in parallel, there is a lot of focus on the Learn project, launched in December 2020, a multilingual learning platform offering workshops, quizzes, courses, lesson plans, and discussion groups calculated for both users and WordPress developers.
Why users and developers support WordPress
Positive feedback in action – developers like working with WordPress and at some point they want to take part in its development. In addition to the satisfaction of a closed ticket or patch that entered the core, this is an opportunity to try your hand, evaluate the level of competence in comparison with developers from more than 50 countries, and improve in a friendly environment. Observing how simple-looking improvements lead to deep discussions, various proposals for implementation and careful testing, you begin to understand that there is no limit to perfection and you stop clinging to the illusion of the perfection of your own code.
You can get an idea of how the community works by visiting the Make WordPress site.
In addition to professional development, WordPress is conferences and meetups held in different parts of the world, which were forced to go online a year ago and during this time have brought participants closer together like never before. The WordCamp Europe conference in Porto, Portugal, has been postponed for the 2nd year in a row, which does not prevent the community from preparing to host WordCamp Europe online from June 7-10, 2021, which promises to be the largest WordPress event this year.
Plugin development companies, large agencies, and hosting companies that provide services designed specifically for WordPress – one-click staging site, monitoring site health, managing automatic updates and other features that relieve developers from routine, sponsor not only events but and developers from different countries developing the WordPress core and doing other areas within the framework of the “Five for the Future” concept.
For those who want to try their hand at core development, Sergey Biryukov, WordPress Core Committer and plugin author working in the Polyglots, Support and Meta teams, and co-founder of the Russian WordPress community, wrote detailed instructions.
If you are in doubt whether WordPress is suitable for a specific project, visit the Russian-language WordPress support forum, which is ranked second in terms of activity after the English-language one.
The original article can be read here
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
WordPress Coding Standards(WPCS) the list of PHP_CodeSniffer (PHPCS) ruleset (sniffs) to check your code inside WordPress. It can improve your code quality and adhere to basic code conventions for WordPress.
Do you work in a team or just want to upgrade a code quality? Then you need to think about a single coding standard. I’m afraid you but if in your team more then one person it doesn’t work without quality control tools. The control quality tool for coding standard names the linter and exists for each programming language.
Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors, and suspicious constructs.
Wikipedia
As example for Python – Pylint, for PHP – PHP_CodeSniffer, for JavaScript – ESLint or JSHint, etc.
The WordPress Coding Standard includes simple rules about spaces and blanks as harder security rules, caching, and etc.
How to install WPCS?
Just use the composer
:
composer require wp-coding-standards/wpcs --dev
When you add any packages for PHP_CodeSniffer you need to add these packages to the scope of PHPCS. The best solution is a package that automatically adds all packages from your vendor in the scope of PHPCS.
composer require dealerdirect/phpcodesniffer-composer-installer --dev
And now you can easy to check the file and fix it:
vendor/bin/phpcs --standard=WordPress path/to/some/file.php
vendor/bin/phpcbf --standard=WordPress path/to/some/file.php
How to setting the PHPStorm?
PHPStorm -> Settings -> Languages & Frameworks -> PHP -> CLI Interpreter and choose the current PHP version.
PHPStorm -> Settings -> Languages & Frameworks -> PHP -> Quality Tools -> PHP_CodeSniffer -> Configuration and click on ‘…‘ button
Fill the PHP_CodeSniffer path:
path/to/vendor/squizlabs/php_codesniffer/bin/phpcs
and fill the Path to phpcbf:
path/to/vendor/squizlabs/php_codesniffer/bin/phpcsbf
Press on Validate button and accept that your paths are correct.
PHPStorm -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer validation:
Checked Show sniff name
In the Coding Standard list, you can see the next packages: WordPress, WordPress-Core, WordPress-Docs, WordPress-Extra. Choose WordPress and save it.
If you violate coding standards, in the editor, the lines will be underlined. If you hover over the underlined line, you will see an error.
As example:
phpcs: WordPress.Security.NonceVerification.Missing: Processing form data without nonce verification.
Where WordPress.Security.NonceVerification.Missing – sniff name and Processing form data without nonce verification. – description.
How to ignore some rules?
Sometimes your code can’t fully compatibility with WPCS. As example:
global $wpdb;
$id = 15;
$my_query = $wpdb->get_results( 'SELECT name FROM my_table WHERE id=' . $id );
In this example a few notices:
- WordPress.DB.PreparedSQL.NotPrepared
- WordPress.DB.DirectDatabaseQuery.NoCaching
- WordPress.DB.DirectDatabaseQuery.DirectQuery
Raw data is a potential XSS backdoor. We can fix this with $wpdb->prepare
, cache some queries is also great for performance, but what do you need to do with a direct query? The right way is adding the ignore rule, but it is very important to understand the reason. If you add an ignore rule, you can read it as a developer’s signature about that line.
global $wpdb;
$id = 15;
$my_query = wp_cache_get( 'my_query' );
if ( ! $my_query ) {
$my_query = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->prepare( 'SELECT name FROM my_table WHERE id=%d', $id )
);
wp_cache_set( 'my_query', $my_query );
}
phpcs:ignore – is ignoring the next line of your code. The best practice you’re php:ignore
with the rule description phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
. So we ignoring only one rule from our coding standard. Also if you need to ignore rule for a few lines of the code then you can use the phpcs:disable
, but don’t forget to enable this rule after:
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$my_query = $wpdb->get_results(
$wpdb->prepare(
'SELECT name FROM my_table WHERE id=%d',
$id
)
);
//phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
The own coding standard based on WPCS
In my opinion for the middle and more size projects need to create their own codings standard. It’s very easy, just create the phpcs.xml
file:
<?xml version="1.0"?>
<ruleset name="AwesomeCS">
<description>Custom coding standards.</description>
<rule ref="WordPress"/>
</ruleset>
We create the AwesomeCS coding standard based on the WordPress coding standards.
Arguments
You can add arguments from CLI for your config. For example, argument extensions that can help you work only with the PHP files:
<ruleset name="AwesomeCS">
<!-- ... -->
<arg value="ps"/>
<arg name="colors"/>
<arg name="parallel" value="100"/>
<arg name="extensions" value="php"/>
<arg name="cache" value=".phpcs.cache"/>
<!-- ... -->
</ruleset>
- The
ps
can show results of check real-time; - The
colors
is just adds the colored output; - The
parallel
checks your files in separate processes. Unfortunately, but this feature based on the PCNTL library and doesn’t works on Non-Unix systems (Windows). But can add the super boost for your speed in the GH actions; - The
extensions
describes the extensions for the checking; - The
cache
is just super boost for the double-checking
Exclude files and directories
Add the list of pattern where phpcs
doesn’t check.
<ruleset name="AwesomeCS">
<!-- ... -->
<exclude-pattern>\.github/*</exclude-pattern>
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>node_modues/*</exclude-pattern>
<exclude-pattern>\.idea/*</exclude-pattern>
<exclude-pattern>assets/*</exclude-pattern>
<!-- ... -->
</ruleset>
The short array syntax
Frankly the short array syntax it’s uncomfortable and legacy, but important for WordPress coding standard. Let’s update it:
<ruleset name="AwesomeCS">
<!-- ... -->
<!-- Allow short array syntax -->
<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
<severity>0</severity>
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
<!-- ... -->
</ruleset>
This is a just example of how to add custom rules in your CS.
The PSR-4 naming
I prefer using the composer autoload, so let’s update CS for support PSR-4 naming:
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="WordPress">
<!-- PSR4 -->
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
</rule>
<!-- ... -->
</ruleset>
Cyclomatic Complexity
Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program’s source code.
Wikipedia
This metric will help control code complications and write simpler functions and methods.
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="4"/>
<property name="absoluteComplexity" value="5"/>
</properties>
</rule>
<!-- ... -->
</ruleset>
- If the cyclomatic complexity is higher than 4, you will see a warning
- If the cyclomatic complexity is higher than 5, you will see the error
Nesting Level
<ruleset name="AwesomeCS">
<!-- ... -->
<rule ref="Generic.Metrics.NestingLevel">
<properties>
<property name="absoluteNestingLevel" value="1"/>
</properties>
</rule>
<!-- ... -->
</ruleset>
If the nesting level is higher than 1, you will see an error.
As example this code will cause an error on CS:
function awesome_function( $items ) {
if ( is_array( $items ) {
foreach( $items as $item ) {
// ...
}
}
}
This code needs to be refactored and used early exit from the method/function:
function awesome_function( $items ) {
if ( ! is_array( $items ) {
return false;
}
foreach( $items as $item ) {
// ...
}
}
PHPCompatibility
Just awesome coding standard PHPCompatibility which you can add the minimal support PHP version and phpcs
will detect in your code any problem for it. It’s really very well library for public plugins when you need to support the form PHP5.6 to PHP7.4 version. Just run your test in php7.4 and this library can help you find any problem with PHP compatibility in 5.6
Let’s install this library and update config:
composer require phpcompatibility/php-compatibility --dev
<ruleset name="AwesomeCS">
<!-- ... -->
<config name="testVersion" value="5.6-"/>
<rule ref="PHPCompatibility"/>
<!-- ... -->
</ruleset>
Thanks to this, you can check the compatibility from PHP5.6 to the version on which you are checking the files.
Add your own config to PHPStorm
File -> Settings -> Editor -> Inspection -> Quality Tools -> PHP_CodeSniffer
In the list of Coding standard select Custom and specify the path to our phpcs.xml
Full config
<?xml version="1.0"?>
<ruleset name="CS">
<description>Custom coding standards.</description>
<config name="testVersion" value="5.6-"/>
<exclude-pattern>\.codeception/*</exclude-pattern>
<exclude-pattern>\.github/*</exclude-pattern>
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>node_modues/*</exclude-pattern>
<exclude-pattern>\.idea/*</exclude-pattern>
<exclude-pattern>assets/*</exclude-pattern>
<arg value="ps"/>
<arg name="colors"/>
<arg name="parallel" value="100"/>
<arg name="extensions" value="php"/>
<arg name="cache" value=".phpcs.cache"/>
<rule ref="WordPress">
<!-- PSR4 -->
<exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
</rule>
<rule ref="PHPCompatibility"/>
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="3"/>
<property name="absoluteComplexity" value="5"/>
</properties>
</rule>
<rule ref="Generic.Metrics.NestingLevel">
<properties>
<property name="absoluteNestingLevel" value="3"/>
</properties>
</rule>
<!-- Allow short array syntax -->
<rule ref="Generic.Arrays.DisallowShortArraySyntax.Found">
<severity>0</severity>
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found"/>
</ruleset>
Composer scripts
Add the scripts to run your CS using the composer scripts. Just add to the composer.json
next code:
{
...
"scripts": {
"cs": "phpcs --standard=.phpcs.xml .",
"cbf": "phpcbf --standard=.phpcs.xml .",
...
}
...
}
And now you can just run your coding standards and code beautifier and fixer:
composer cs
composer cbf
CS in the GitHub Actions
Create the file .github/workflows/php.yml
in your project:
name: My GH Actions
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: Run CS
run: vendor/bin/phpcs --standard=phpcs.xml .
After push action, your code will be checked on coding standards and you can see results on the GitHub.
If after this detailed article you don’t implement CS verification in your project, then I will come to you in a dream and kick your ass.
What the next? You can read how to write your own sniffs for PHP_CodeSniffer.
The original article can be read here
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
WordPress in the latest version 5.5.3 gives a 404 error when trying to enable the newly released PHP 8. Why?
Officially, WordPress will only be compatible with PHP 8 starting with version 5.6, which is scheduled for December 8, 2020. The RC version of the WordPress 5.6 core works correctly with PHP 8, the issue has been fixed. However, it is interesting to understand what is the source of the problem.
First, let’s try to answer the question, what is the value of the expression
'' < 0 //(empty string less than zero)?
The first answer that comes to mind is false. An empty string is reduced to zero, the comparison is 0 < 0, the result is false.
This has always been the case in PHP, and before PHP 8, the result of the expression is false. But not in PHP 8. Here the result of the expression is true, and it is officially announced. Comparison with a numeric string uses a number comparison. But the empty string is not numeric and PHP 8 uses string comparison: ' ' < '0' and the result is true.
What does this have to do with WordPress?
The core has a method that is called on every request: \WP_Query::parse_query. It contains lines
if ( !is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
$qv['p'] = 0;
$qv['error'] = '404';
...
In most cases, $qv['p'] contains an empty string, which triggers the if and sets a 404 error.
In WordPress 5.6, the comparison string looks like this:
if ( !is_scalar( $qv['p'] ) || (int)$qv['p'] < 0 ) { ...
Which fixes the problem in PHP 8 and works correctly in all PHP versions.
You shouldn’t use implicit casting, especially when developing code that should work under PHP 8.
The original article can be read here
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
What we need:
- Access to the server with ssh
- Installed on the server WP-CLI
How to install WP-CLI on the server?
- curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
- php wp-cli.phar --info (should output the WP-CLI version)
- chmod +x wp-cli.phar
- sudo mv wp-cli.phar /usr/local/bin/wp
Step-by-step instructions on how to quickly transfer a site. When you need to transfer to the dev version, all content and the database, or make a deployment
- Ssh connect to the server
- Go to the folder with the site cd /path/to/wp/folder
- We execute the command wp core download --allow-root
- Create DB in host panel
- We need to configure our wp-confing.php file for this we execute this command replacing the parameters with our data wp core config --dbname=YOUR_DATABASE_NAME --dbuser=YOUR_DATABASE_USER --dbpass=YOUR_DATABASE_PASSWORD --dbhost=if_differs_from_a_localhost --dbprefix=dbprefix
- We need to dump the database from the local machine and upload it to a folder on the server
- We import the database wp --quiet db import /path/to/file/exported-wp-sql.sql
- Now we need to change all URLs from local to main domain wp search-replace http://old-url.com https://new-url.com --all-tables
- We transfer all the files that are in the folder wp-content/ (if you have macOS \ Linux \ Unix you can execute the command in the terminal scp -r remoteuser@remoteserver:/remote/folder/ /path/to/wp/folder)
Now our site has been successfully transferred to the server
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!
Where to start and why do you need it?
You need to install Composer locally, here’s a step-by-step guide on how to do it:
In the terminal run the command curl -sS https://getcomposer.org/installer -o composer-setup.php sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer composer -v
If you saw this conclusion, then everything went well.
Large and medium plugins or themes always have a lot of files and classes that we need to include via require, require_once, or include.
As a result, we get a huge feed of file connections in function.php or in the main plugin file it looks like this
Six months later, when you open the project, if you did not leave comments in the code, then you no longer remember what the file is responsible for and where you need to make, for example, edits or fix a bug.
It is very inconvenient when adding new functionality to connect each time another file (main thing is not to forget to do this).
And here Composer comes to the rescue.
First step
Go to the root folder with your theme or plugin and create composer. json, it can be created in several ways
- We run the command in the composer init terminal and answer a few questions, Composer itself will generate a standard file
- Create manually
I choose the first option
{
"name": "user/name_project",
"authors": [
{
"name": "iWPdev",
"email": "
iw****@ou*****.com
"
}
],
"require": {
}
}
Next, we need to add the autoloading capability and the namespace of our classes, and a few more parameters for standardization.
{
"name": "user/name_project",
"description": "",
"license": "GPL-2.0",
"keywords": [],
"homepage": "https://exemple.com/",
"type": "wordpress-plugin", // If it's a plugin and wordpress-themes if it's a theme
"authors": [
{
"name": "iWPdev",
"email": "
iw****@ou*****.com
"
}
],
"support": {
"issues": "https://exemple.com/"
},
"config": {
"platform": {
"php": "7.2.5"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"require": {},
"autoload": {
"psr-4": {
"iWPdev\\": "includes/",
"iWPdev\\Admin\\": " admin/",
}
}
}
We are interested in the code in bold, it makes it clear to Composer where to get our files.
A folder structure that looks like this:
Root project
| ---- composer.json
| ---- includes
| ---- nameClass.php
| ---- admin
| ---- nameClass.php
I structure in my projects like this:
Second step
Execute the command in a terminal composer dump-autoload -o
If you are working in PHPStorm, then it will be enough for you to click the button in the open file composer.json Install or Update
Third step
Now all we need to do is include one file in function.php or the main file of our plugin
require_once __DIR__ . '/vendor/autoload.php';
Now Composer does everything for us, it connects all files if it sees the initialization of a class in our code, and we always forget that we need to connect our files with classes by hand!
Related posts
Insights and Tips from My Journey
- Category:
- Dev
Carbon Fields VS ACF PRO Gutenberg blocks
- Category:
- Dev
Step-by-Step Guide to Automatically Create Patterns in WordPress
- Category:
- Dev
- Live coding
Creating a Plugin for WordPress Part 3. Creating a Single Post Template and Displaying Carbon Fields
Ready to Take Your Project
to the Next Level?
Let’s bring your vision to life with expert development and custom solutions.
Contact us now and get started on transforming your ideas into reality!