Skip to content
This repository was archived by the owner on Dec 18, 2025. It is now read-only.

Commit e417761

Browse files
authored
Merge pull request #57 from creode/feature/refactor_make_block_command
Refactors the make block command to make it easier to maintain moving forwards.
2 parents 9a01bbd + 385a325 commit e417761

13 files changed

Lines changed: 691 additions & 256 deletions
Lines changed: 12 additions & 248 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
use Creode_Blocks\Make_Block;
4+
25
/**
36
* Make Command class.
47
*
@@ -30,258 +33,19 @@ class Make_Block_Command {
3033
* @param array $optional_args List of optional arguments.
3134
*/
3235
public function __invoke( $args, $optional_args ) {
33-
$theme = ! empty( $optional_args['theme'] ) ? $optional_args['theme'] : null;
34-
$theme_base_path = $this->get_theme_base_path( $theme );
35-
36+
// Set the block label.
3637
$block_label = $args[0];
3738

38-
$block_class_name = $this->generate_block_class_name( $block_label );
39-
$block_slug_name = $this->generate_block_slug_name( $block_label );
40-
$block_folder_path = $this->create_block_folder_structure( $theme_base_path, $block_slug_name );
41-
$theme_slug = $this->get_theme_slug( $theme );
42-
43-
$this->make_block_class( $block_slug_name, $block_label, $block_class_name, $block_folder_path, $theme_slug );
44-
$this->make_block_template( $block_slug_name, $block_label, $block_class_name, $block_folder_path );
45-
$this->add_block_to_loader_file( $block_class_name, "/$block_slug_name/class-$block_slug_name-block.php", $theme );
46-
47-
// Tell the user to require the block to the themes file and provide location.
48-
WP_CLI::success( 'Block created successfully.' );
49-
}
50-
51-
/**
52-
* Generates a valid class name for the block.
53-
*
54-
* @param string $block_label
55-
*
56-
* @return string
57-
*/
58-
protected function generate_block_class_name( $block_label ) {
59-
// Convert to title case.
60-
$block_label = ucwords( $block_label );
61-
62-
// Convert any spaces to dashes.
63-
$block_class_name = str_replace( ' ', '_', $block_label );
64-
65-
// Run regex to strip anything out except for letters both upper and lowercase and dashes.
66-
return preg_replace( '/[^a-zA-Z0-9_]/', '', $block_class_name ) . '_Block';
67-
}
68-
69-
/**
70-
* Generates block slug name based on it's class name.
71-
*
72-
* @param string $block_class_name
73-
*
74-
* @return string
75-
*/
76-
protected function generate_block_slug_name( $block_label ) {
77-
$block_class_name = $this->generate_block_class_name( $block_label );
78-
79-
// Remove the _Block suffix.
80-
$block_class_name = str_replace( '_Block', '', $block_class_name );
81-
82-
return strtolower( str_replace( '_', '-', $block_class_name ) );
83-
}
84-
85-
/**
86-
* Main functionality for creating and saving the block class.
87-
*
88-
* @param string $block_slug_name The slug of the block.
89-
* @param string $block_label The label of the block.
90-
* @param string $block_class_name The class name of the block.
91-
* @param string $block_folder_path The path to the block folder.
92-
* @param string $theme_slug The slug of the theme.
93-
*
94-
* @return void
95-
*/
96-
protected function make_block_class( $block_slug_name, $block_label, $block_class_name, $block_folder_path, $theme_slug ) {
97-
$theme = wp_get_theme();
98-
99-
// Load the contents of the stub file.
100-
$block_class_stub = file_get_contents( CREODE_BLOCKS_PLUGIN_FOLDER . 'commands/stubs/class-block.php' );
101-
102-
// Replace the placeholders in the stub file.
103-
$block_class_stub = $this->replace_stub_placeholders(
104-
$block_class_stub,
105-
array(
106-
':BLOCK_NAME' => $block_slug_name,
107-
':BLOCK_LABEL' => $block_label,
108-
':BLOCK_TEMPLATE' => "__DIR__ . '/templates/block.php'",
109-
':BLOCK_CLASS_NAME' => $block_class_name,
110-
':THEME_SLUG' => $theme_slug,
111-
':THEME_NAME' => $theme->get( 'Name' ),
112-
':BLOCK_VERSION' => $this->get_block_plugin_version(),
113-
)
114-
);
115-
116-
// Setup block class filepath.
117-
$block_class_file_path = $block_folder_path . '/class-' . $block_slug_name . '-block.php';
118-
119-
// Write the stub file to the block class file.
120-
file_put_contents( $block_class_file_path, $block_class_stub );
121-
}
122-
123-
/**
124-
* Takes an array of replacements and replaces them in the stub.
125-
*
126-
* @param string $stub The stub file contents.
127-
* @param array $replacements An array of placeholders and their replacements.
128-
*
129-
* @return string
130-
*/
131-
protected function replace_stub_placeholders( $stub, $replacements ) {
132-
foreach ( $replacements as $key => $value ) {
133-
$stub = str_replace( $key, $value, $stub );
134-
}
135-
136-
return $stub;
137-
}
138-
139-
/**
140-
* Gets the theme slug.
141-
*
142-
* @param string $theme Optional slug of the theme.
143-
*
144-
* @return string
145-
*/
146-
private function get_theme_slug( ?string $theme ): string {
147-
$theme_slug = $theme;
148-
if ( is_null( $theme_slug ) ) {
149-
$theme_slug = get_stylesheet();
150-
}
151-
152-
return $theme_slug;
153-
}
154-
155-
/**
156-
* Get the base path of the theme.
157-
*
158-
* @param string|null $theme Optional slug of the theme.
159-
*
160-
* @return string Path to theme.
161-
*/
162-
private function get_theme_base_path( ?string $theme = null ) {
163-
if ( is_null( $theme ) ) {
164-
$theme_base_path = get_stylesheet_directory();
165-
} else {
166-
$theme_base_path = get_theme_root() . '/' . $theme;
167-
}
168-
169-
if ( ! file_exists( $theme_base_path ) ) {
170-
WP_CLI::error( 'Theme does not exist.' );
171-
}
172-
173-
return $theme_base_path;
174-
}
175-
176-
/**
177-
* Creates block folder structure.
178-
*
179-
* @param string $theme_base_path Path to theme.
180-
* @param string $block_folder_name Block folder name.
181-
*
182-
* @return string Path to folder where the block will go.
183-
*/
184-
private function create_block_folder_structure( string $theme_base_path, string $block_folder_name ) {
185-
// Create blocks folder.
186-
$blocks_folder = $theme_base_path . '/blocks';
187-
if ( ! file_exists( $blocks_folder ) ) {
188-
mkdir( $blocks_folder );
189-
}
190-
191-
// Create block folder.
192-
$block_folder = $blocks_folder . '/' . $block_folder_name;
193-
if ( file_exists( $block_folder ) ) {
194-
WP_CLI::error( "Block \"$block_folder_name\" already exists." );
195-
}
196-
197-
mkdir( $block_folder );
198-
199-
// Create templates folder.
200-
$templates_folder = $block_folder . '/templates';
201-
if ( ! file_exists( $templates_folder ) ) {
202-
mkdir( $templates_folder );
203-
}
204-
205-
return $block_folder;
206-
}
39+
// Set the theme slug.
40+
$block_theme_slug = $optional_args['theme'] ?? null;
20741

208-
/**
209-
* Generates a basic block template file.
210-
*
211-
* @param string $block_slug_name The slug of the block.
212-
* @param string $block_label The label of the block.
213-
* @param string $block_class_name The class name of the block.
214-
* @param string $block_folder_path The path to the block folder.
215-
*/
216-
private function make_block_template( string $block_slug_name, string $block_label, string $block_class_name, string $block_folder_path ) {
217-
$theme = wp_get_theme();
218-
$block_html_base_class = $block_slug_name;
219-
220-
// Remove suffix from block base class.
221-
if ( '-block' === substr( $block_html_base_class, -6 ) ) {
222-
$block_html_base_class = substr( $block_html_base_class, 0, -6 );
223-
}
224-
225-
// Load the content of the stub file.
226-
$content = file_get_contents( CREODE_BLOCKS_PLUGIN_FOLDER . 'commands/stubs/templates/block.php' );
227-
228-
// Replace placeholders.
229-
$content = $this->replace_stub_placeholders(
230-
$content,
231-
array(
232-
':THEME_NAME' => $theme->get( 'Name' ),
233-
':BLOCK_NAME' => $block_slug_name,
234-
':BLOCK_LABEL' => $block_label,
235-
':BLOCK_CLASS' => $block_class_name,
236-
':BLOCK_HTML_BASE_CLASS' => $block_html_base_class,
237-
)
238-
);
239-
240-
// Write the content to the template file.
241-
file_put_contents( $block_folder_path . '/templates/block.php', $content );
242-
}
243-
244-
/**
245-
* Adds code to load and initialize a block within the theme.
246-
*
247-
* @param string $block_class_name The block class name.
248-
* @param string $block_class_path A relative path (from the blocks directory) to the block class file.
249-
* @param string|null $theme Optional slug of the theme.
250-
*/
251-
private function add_block_to_loader_file( string $block_class_name, string $block_class_path, ?string $theme = null ) {
252-
$blocks_directory_path = $this->get_theme_base_path( $theme ) . '/blocks';
253-
254-
if ( ! file_exists( $blocks_directory_path . '/all.php' ) ) {
255-
$theme = wp_get_theme();
256-
$all_file_contents = file_get_contents( CREODE_BLOCKS_PLUGIN_FOLDER . 'commands/stubs/all.php' );
257-
258-
$all_file_contents = $this->replace_stub_placeholders(
259-
$all_file_contents,
260-
array(
261-
':THEME_NAME' => $theme->get( 'Name' ),
262-
)
263-
);
264-
265-
file_put_contents( $blocks_directory_path . '/all.php', $all_file_contents );
266-
}
267-
268-
file_put_contents( $blocks_directory_path . '/all.php', PHP_EOL . 'require_once __DIR__ . \'' . $block_class_path . '\';', FILE_APPEND );
269-
file_put_contents( $blocks_directory_path . '/all.php', PHP_EOL . $block_class_name . '::init();', FILE_APPEND );
270-
file_put_contents( $blocks_directory_path . '/all.php', PHP_EOL, FILE_APPEND );
271-
}
272-
273-
/**
274-
* Determines the version of the block plugin.
275-
*
276-
* @return string
277-
*/
278-
private function get_block_plugin_version(): string {
279-
// Read it from the composer.lock file?
280-
$block_version = '1.0.0';
281-
if ( class_exists( '\Composer\InstalledVersions' ) ) {
282-
$block_version = \Composer\InstalledVersions::getPrettyVersion( 'creode/wordpress-blocks' );
42+
try {
43+
// Create the block.
44+
new Make_Block( $block_label, $block_theme_slug );
45+
} catch ( Exception $e ) {
46+
WP_CLI::error( $e->getMessage() );
28347
}
28448

285-
return $block_version;
49+
WP_CLI::success( 'Block created successfully.' );
28650
}
28751
}

includes/class-make-block.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace Creode_Blocks;
4+
5+
use Creode_Blocks\Make_Block\Actions\{Create_New_Block_Files, Rename_Files, Replace_File_Contents, Setup_Block_Include, Setup_Scss_Include};
6+
use Creode_Blocks\Make_Block\Services\Block_Details;
7+
use Creode_Blocks\Make_Block\Services\Block_Replacements;
8+
9+
/**
10+
* Handles the creation of block files in desired location.
11+
*/
12+
class Make_Block {
13+
/**
14+
* The label of the block.
15+
*
16+
* @var string
17+
*/
18+
protected $label;
19+
20+
/**
21+
* The slug of the theme.
22+
*
23+
* @var string
24+
*/
25+
protected $theme_slug;
26+
27+
/**
28+
* The class for holding the block details.
29+
*
30+
* @var Block_Details
31+
*/
32+
protected $block_details;
33+
34+
/**
35+
* The class for holding the block replacements.
36+
*
37+
* @var Block_Replacements
38+
*/
39+
protected $block_replacements;
40+
41+
/**
42+
* The class for creating new block files.
43+
*
44+
* @var Create_New_Block_Files
45+
*/
46+
public $create_new_block_files;
47+
48+
/**
49+
* The class for renaming files.
50+
*
51+
* @var Rename_Files
52+
*/
53+
public $rename_files;
54+
55+
/**
56+
* The class for replacing file contents.
57+
*
58+
* @var Replace_File_Contents
59+
*/
60+
public $replace_file_contents;
61+
62+
/**
63+
* The class for setting up the block include.
64+
*
65+
* @var Setup_Block_Include
66+
*/
67+
public $setup_block_include;
68+
69+
/**
70+
* Create the block.
71+
*
72+
* @param string $label The label of the block.
73+
* @param string $theme_slug The slug of the theme.
74+
*/
75+
public function __construct( string $label, ?string $theme_slug = null ) {
76+
$this->label = $label;
77+
$this->theme_slug = $theme_slug;
78+
79+
// Get the package path.
80+
$package_path = $this->get_package_path( $this->theme_slug );
81+
82+
// Create a new block details and replacements classes.
83+
$this->block_details = new Block_Details( $this->label, $package_path );
84+
$this->block_replacements = new Block_Replacements( $this->block_details );
85+
86+
// Call functionality to create the new block files.
87+
$this->create_new_block_files = new Create_New_Block_Files( $this->block_details );
88+
$this->rename_files = new Rename_Files( $this->block_details, $this->block_replacements );
89+
$this->replace_file_contents = new Replace_File_Contents( $this->block_details, $this->block_replacements );
90+
$this->setup_block_include = new Setup_Block_Include( $this->block_details, $this->block_replacements );
91+
}
92+
93+
/**
94+
* Get the package path.
95+
*
96+
* @param string|null $theme_slug The slug of the theme.
97+
*
98+
* @return string
99+
*/
100+
protected function get_package_path( ?string $theme_slug ) {
101+
// TODO: Implement functionality for also using a plugin path.
102+
103+
// If theme is not provided, use the current theme.
104+
if ( is_null( $theme_slug ) ) {
105+
$theme_base_path = get_stylesheet_directory();
106+
} else {
107+
$theme_base_path = get_theme_root() . '/' . $theme_slug;
108+
}
109+
110+
return $theme_base_path . '/blocks';
111+
}
112+
}

0 commit comments

Comments
 (0)