@mytechtoday/augment-extensions 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/domain-rules/wordpress/README.md +163 -0
- package/augment-extensions/domain-rules/wordpress/module.json +32 -0
- package/augment-extensions/domain-rules/wordpress/rules/coding-standards.md +617 -0
- package/augment-extensions/domain-rules/wordpress/rules/directory-structure.md +270 -0
- package/augment-extensions/domain-rules/wordpress/rules/file-patterns.md +423 -0
- package/augment-extensions/domain-rules/wordpress/rules/gutenberg-blocks.md +493 -0
- package/augment-extensions/domain-rules/wordpress/rules/performance.md +568 -0
- package/augment-extensions/domain-rules/wordpress/rules/plugin-development.md +510 -0
- package/augment-extensions/domain-rules/wordpress/rules/project-detection.md +251 -0
- package/augment-extensions/domain-rules/wordpress/rules/rest-api.md +501 -0
- package/augment-extensions/domain-rules/wordpress/rules/security.md +564 -0
- package/augment-extensions/domain-rules/wordpress/rules/theme-development.md +388 -0
- package/augment-extensions/domain-rules/wordpress/rules/woocommerce.md +441 -0
- package/augment-extensions/domain-rules/wordpress-plugin/README.md +139 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/ajax-plugin.md +1599 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/custom-post-type-plugin.md +1727 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block-plugin.md +428 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/gutenberg-block.md +422 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/mvc-plugin.md +1623 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/object-oriented-plugin.md +1343 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/rest-endpoint.md +734 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/settings-page-plugin.md +1350 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/simple-procedural-plugin.md +503 -0
- package/augment-extensions/domain-rules/wordpress-plugin/examples/singleton-plugin.md +971 -0
- package/augment-extensions/domain-rules/wordpress-plugin/module.json +53 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/activation-hooks.md +770 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/admin-interface.md +874 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/ajax-handlers.md +629 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/asset-management.md +559 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/context-providers.md +709 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/cron-jobs.md +736 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/database-management.md +1057 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/documentation-standards.md +463 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/frontend-functionality.md +478 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/gutenberg-blocks.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/internationalization.md +416 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/migration.md +667 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/performance-optimization.md +878 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-architecture.md +693 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/plugin-structure.md +352 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/rest-api.md +818 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/scaffolding-workflow.md +624 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/security-best-practices.md +866 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing-patterns.md +1165 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/testing.md +414 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/vscode-integration.md +751 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/woocommerce-integration.md +949 -0
- package/augment-extensions/domain-rules/wordpress-plugin/rules/wordpress-org-submission.md +458 -0
- package/augment-extensions/examples/gutenberg-block-plugin/README.md +101 -0
- package/augment-extensions/examples/gutenberg-block-plugin/examples/testimonial-block.md +428 -0
- package/augment-extensions/examples/gutenberg-block-plugin/module.json +40 -0
- package/augment-extensions/examples/rest-api-plugin/README.md +98 -0
- package/augment-extensions/examples/rest-api-plugin/examples/task-manager-api.md +1299 -0
- package/augment-extensions/examples/rest-api-plugin/module.json +40 -0
- package/augment-extensions/examples/woocommerce-extension/README.md +98 -0
- package/augment-extensions/examples/woocommerce-extension/examples/product-customizer.md +763 -0
- package/augment-extensions/examples/woocommerce-extension/module.json +40 -0
- package/augment-extensions/workflows/wordpress-plugin/README.md +232 -0
- package/augment-extensions/workflows/wordpress-plugin/ai-prompts.md +839 -0
- package/augment-extensions/workflows/wordpress-plugin/bead-decomposition-patterns.md +854 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/complete-plugin-example.md +540 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/custom-post-type-example.md +1083 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/feature-addition-workflow.md +669 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/plugin-creation-workflow.md +597 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/secure-form-handler-example.md +925 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/security-audit-workflow.md +752 -0
- package/augment-extensions/workflows/wordpress-plugin/examples/wordpress-org-submission-workflow.md +773 -0
- package/augment-extensions/workflows/wordpress-plugin/module.json +49 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/best-practices.md +942 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/development-workflow.md +702 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/submission-workflow.md +728 -0
- package/augment-extensions/workflows/wordpress-plugin/rules/testing-workflow.md +775 -0
- package/cli/dist/cli.js +5 -1
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/show.d.ts.map +1 -1
- package/cli/dist/commands/show.js +41 -0
- package/cli/dist/commands/show.js.map +1 -1
- package/modules.md +52 -0
- package/package.json +1 -1
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
# WordPress Plugin Development Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This document provides step-by-step workflows for WordPress plugin development, from basic plugins to complex functionality.
|
|
6
|
+
|
|
7
|
+
## Workflow 1: Create Custom Plugin
|
|
8
|
+
|
|
9
|
+
### Step 1: Initialize Plugin Structure
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Create plugin directory
|
|
13
|
+
mkdir wp-content/plugins/my-plugin
|
|
14
|
+
cd wp-content/plugins/my-plugin
|
|
15
|
+
|
|
16
|
+
# Create directory structure
|
|
17
|
+
mkdir includes admin public assets assets/css assets/js languages
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Step 2: Create Main Plugin File
|
|
21
|
+
|
|
22
|
+
**my-plugin.php**:
|
|
23
|
+
```php
|
|
24
|
+
<?php
|
|
25
|
+
/**
|
|
26
|
+
* Plugin Name: My Plugin
|
|
27
|
+
* Plugin URI: https://example.com/my-plugin
|
|
28
|
+
* Description: A custom WordPress plugin
|
|
29
|
+
* Version: 1.0.0
|
|
30
|
+
* Requires at least: 6.0
|
|
31
|
+
* Requires PHP: 7.4
|
|
32
|
+
* Author: Your Name
|
|
33
|
+
* Author URI: https://example.com
|
|
34
|
+
* License: GPL v2 or later
|
|
35
|
+
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
|
36
|
+
* Text Domain: my-plugin
|
|
37
|
+
* Domain Path: /languages
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
// Prevent direct access
|
|
41
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
42
|
+
exit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Define plugin constants
|
|
46
|
+
define( 'MY_PLUGIN_VERSION', '1.0.0' );
|
|
47
|
+
define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
|
|
48
|
+
define( 'MY_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
|
49
|
+
|
|
50
|
+
// Include core files
|
|
51
|
+
require_once MY_PLUGIN_PATH . 'includes/class-my-plugin.php';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Initialize the plugin
|
|
55
|
+
*/
|
|
56
|
+
function my_plugin_init() {
|
|
57
|
+
$plugin = new My_Plugin();
|
|
58
|
+
$plugin->run();
|
|
59
|
+
}
|
|
60
|
+
add_action( 'plugins_loaded', 'my_plugin_init' );
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Activation hook
|
|
64
|
+
*/
|
|
65
|
+
function my_plugin_activate() {
|
|
66
|
+
// Create database tables, add options, etc.
|
|
67
|
+
require_once MY_PLUGIN_PATH . 'includes/class-activator.php';
|
|
68
|
+
My_Plugin_Activator::activate();
|
|
69
|
+
}
|
|
70
|
+
register_activation_hook( __FILE__, 'my_plugin_activate' );
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Deactivation hook
|
|
74
|
+
*/
|
|
75
|
+
function my_plugin_deactivate() {
|
|
76
|
+
// Clean up temporary data
|
|
77
|
+
require_once MY_PLUGIN_PATH . 'includes/class-deactivator.php';
|
|
78
|
+
My_Plugin_Deactivator::deactivate();
|
|
79
|
+
}
|
|
80
|
+
register_deactivation_hook( __FILE__, 'my_plugin_deactivate' );
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Step 3: Create Core Plugin Class
|
|
84
|
+
|
|
85
|
+
**includes/class-my-plugin.php**:
|
|
86
|
+
```php
|
|
87
|
+
<?php
|
|
88
|
+
/**
|
|
89
|
+
* Core plugin class
|
|
90
|
+
*/
|
|
91
|
+
class My_Plugin {
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Plugin version
|
|
95
|
+
*/
|
|
96
|
+
const VERSION = '1.0.0';
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Initialize the plugin
|
|
100
|
+
*/
|
|
101
|
+
public function run() {
|
|
102
|
+
$this->load_dependencies();
|
|
103
|
+
$this->define_admin_hooks();
|
|
104
|
+
$this->define_public_hooks();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Load required dependencies
|
|
109
|
+
*/
|
|
110
|
+
private function load_dependencies() {
|
|
111
|
+
require_once MY_PLUGIN_PATH . 'admin/class-admin.php';
|
|
112
|
+
require_once MY_PLUGIN_PATH . 'public/class-public.php';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Register admin hooks
|
|
117
|
+
*/
|
|
118
|
+
private function define_admin_hooks() {
|
|
119
|
+
$admin = new My_Plugin_Admin();
|
|
120
|
+
|
|
121
|
+
add_action( 'admin_enqueue_scripts', array( $admin, 'enqueue_styles' ) );
|
|
122
|
+
add_action( 'admin_enqueue_scripts', array( $admin, 'enqueue_scripts' ) );
|
|
123
|
+
add_action( 'admin_menu', array( $admin, 'add_admin_menu' ) );
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Register public hooks
|
|
128
|
+
*/
|
|
129
|
+
private function define_public_hooks() {
|
|
130
|
+
$public = new My_Plugin_Public();
|
|
131
|
+
|
|
132
|
+
add_action( 'wp_enqueue_scripts', array( $public, 'enqueue_styles' ) );
|
|
133
|
+
add_action( 'wp_enqueue_scripts', array( $public, 'enqueue_scripts' ) );
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Step 4: Create Admin Class
|
|
139
|
+
|
|
140
|
+
**admin/class-admin.php**:
|
|
141
|
+
```php
|
|
142
|
+
<?php
|
|
143
|
+
/**
|
|
144
|
+
* Admin-specific functionality
|
|
145
|
+
*/
|
|
146
|
+
class My_Plugin_Admin {
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Enqueue admin styles
|
|
150
|
+
*/
|
|
151
|
+
public function enqueue_styles() {
|
|
152
|
+
wp_enqueue_style(
|
|
153
|
+
'my-plugin-admin',
|
|
154
|
+
MY_PLUGIN_URL . 'assets/css/admin.css',
|
|
155
|
+
array(),
|
|
156
|
+
MY_PLUGIN_VERSION
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Enqueue admin scripts
|
|
162
|
+
*/
|
|
163
|
+
public function enqueue_scripts() {
|
|
164
|
+
wp_enqueue_script(
|
|
165
|
+
'my-plugin-admin',
|
|
166
|
+
MY_PLUGIN_URL . 'assets/js/admin.js',
|
|
167
|
+
array( 'jquery' ),
|
|
168
|
+
MY_PLUGIN_VERSION,
|
|
169
|
+
true
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Add admin menu
|
|
175
|
+
*/
|
|
176
|
+
public function add_admin_menu() {
|
|
177
|
+
add_menu_page(
|
|
178
|
+
__( 'My Plugin', 'my-plugin' ),
|
|
179
|
+
__( 'My Plugin', 'my-plugin' ),
|
|
180
|
+
'manage_options',
|
|
181
|
+
'my-plugin',
|
|
182
|
+
array( $this, 'display_admin_page' ),
|
|
183
|
+
'dashicons-admin-generic',
|
|
184
|
+
30
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Display admin page
|
|
190
|
+
*/
|
|
191
|
+
public function display_admin_page() {
|
|
192
|
+
// Check user capabilities
|
|
193
|
+
if ( ! current_user_can( 'manage_options' ) ) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
?>
|
|
198
|
+
<div class="wrap">
|
|
199
|
+
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
|
200
|
+
<form method="post" action="options.php">
|
|
201
|
+
<?php
|
|
202
|
+
settings_fields( 'my_plugin_options' );
|
|
203
|
+
do_settings_sections( 'my-plugin' );
|
|
204
|
+
submit_button();
|
|
205
|
+
?>
|
|
206
|
+
</form>
|
|
207
|
+
</div>
|
|
208
|
+
<?php
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Step 5: Create Public Class
|
|
214
|
+
|
|
215
|
+
**public/class-public.php**:
|
|
216
|
+
```php
|
|
217
|
+
<?php
|
|
218
|
+
/**
|
|
219
|
+
* Public-facing functionality
|
|
220
|
+
*/
|
|
221
|
+
class My_Plugin_Public {
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Enqueue public styles
|
|
225
|
+
*/
|
|
226
|
+
public function enqueue_styles() {
|
|
227
|
+
wp_enqueue_style(
|
|
228
|
+
'my-plugin-public',
|
|
229
|
+
MY_PLUGIN_URL . 'assets/css/public.css',
|
|
230
|
+
array(),
|
|
231
|
+
MY_PLUGIN_VERSION
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Enqueue public scripts
|
|
237
|
+
*/
|
|
238
|
+
public function enqueue_scripts() {
|
|
239
|
+
wp_enqueue_script(
|
|
240
|
+
'my-plugin-public',
|
|
241
|
+
MY_PLUGIN_URL . 'assets/js/public.js',
|
|
242
|
+
array( 'jquery' ),
|
|
243
|
+
MY_PLUGIN_VERSION,
|
|
244
|
+
true
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Step 6: Create Uninstall Script
|
|
251
|
+
|
|
252
|
+
**uninstall.php**:
|
|
253
|
+
```php
|
|
254
|
+
<?php
|
|
255
|
+
/**
|
|
256
|
+
* Fired when the plugin is uninstalled
|
|
257
|
+
*/
|
|
258
|
+
|
|
259
|
+
// If uninstall not called from WordPress, exit
|
|
260
|
+
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
261
|
+
exit;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Delete plugin options
|
|
265
|
+
delete_option( 'my_plugin_option' );
|
|
266
|
+
|
|
267
|
+
// Delete custom database tables
|
|
268
|
+
global $wpdb;
|
|
269
|
+
$table_name = $wpdb->prefix . 'my_plugin_table';
|
|
270
|
+
$wpdb->query( "DROP TABLE IF EXISTS {$table_name}" );
|
|
271
|
+
|
|
272
|
+
// Clear scheduled hooks
|
|
273
|
+
wp_clear_scheduled_hook( 'my_plugin_cron_hook' );
|
|
274
|
+
|
|
275
|
+
// Delete transients
|
|
276
|
+
delete_transient( 'my_plugin_transient' );
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Workflow 2: Add Custom Post Type
|
|
280
|
+
|
|
281
|
+
### Step 1: Register Custom Post Type
|
|
282
|
+
|
|
283
|
+
**includes/class-post-types.php**:
|
|
284
|
+
```php
|
|
285
|
+
<?php
|
|
286
|
+
/**
|
|
287
|
+
* Register custom post types
|
|
288
|
+
*/
|
|
289
|
+
class My_Plugin_Post_Types {
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Initialize
|
|
293
|
+
*/
|
|
294
|
+
public function init() {
|
|
295
|
+
add_action( 'init', array( $this, 'register_book_post_type' ) );
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Register Book post type
|
|
300
|
+
*/
|
|
301
|
+
public function register_book_post_type() {
|
|
302
|
+
$labels = array(
|
|
303
|
+
'name' => __( 'Books', 'my-plugin' ),
|
|
304
|
+
'singular_name' => __( 'Book', 'my-plugin' ),
|
|
305
|
+
'add_new' => __( 'Add New', 'my-plugin' ),
|
|
306
|
+
'add_new_item' => __( 'Add New Book', 'my-plugin' ),
|
|
307
|
+
'edit_item' => __( 'Edit Book', 'my-plugin' ),
|
|
308
|
+
'new_item' => __( 'New Book', 'my-plugin' ),
|
|
309
|
+
'view_item' => __( 'View Book', 'my-plugin' ),
|
|
310
|
+
'search_items' => __( 'Search Books', 'my-plugin' ),
|
|
311
|
+
'not_found' => __( 'No books found', 'my-plugin' ),
|
|
312
|
+
'not_found_in_trash' => __( 'No books found in Trash', 'my-plugin' ),
|
|
313
|
+
'menu_name' => __( 'Books', 'my-plugin' ),
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
$args = array(
|
|
317
|
+
'labels' => $labels,
|
|
318
|
+
'public' => true,
|
|
319
|
+
'publicly_queryable' => true,
|
|
320
|
+
'show_ui' => true,
|
|
321
|
+
'show_in_menu' => true,
|
|
322
|
+
'query_var' => true,
|
|
323
|
+
'rewrite' => array( 'slug' => 'book' ),
|
|
324
|
+
'capability_type' => 'post',
|
|
325
|
+
'has_archive' => true,
|
|
326
|
+
'hierarchical' => false,
|
|
327
|
+
'menu_position' => 20,
|
|
328
|
+
'menu_icon' => 'dashicons-book',
|
|
329
|
+
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
|
|
330
|
+
'show_in_rest' => true, // Enable Gutenberg editor
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
register_post_type( 'book', $args );
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Step 2: Register Custom Taxonomy
|
|
339
|
+
|
|
340
|
+
```php
|
|
341
|
+
/**
|
|
342
|
+
* Register Genre taxonomy
|
|
343
|
+
*/
|
|
344
|
+
public function register_genre_taxonomy() {
|
|
345
|
+
$labels = array(
|
|
346
|
+
'name' => __( 'Genres', 'my-plugin' ),
|
|
347
|
+
'singular_name' => __( 'Genre', 'my-plugin' ),
|
|
348
|
+
'search_items' => __( 'Search Genres', 'my-plugin' ),
|
|
349
|
+
'all_items' => __( 'All Genres', 'my-plugin' ),
|
|
350
|
+
'parent_item' => __( 'Parent Genre', 'my-plugin' ),
|
|
351
|
+
'parent_item_colon' => __( 'Parent Genre:', 'my-plugin' ),
|
|
352
|
+
'edit_item' => __( 'Edit Genre', 'my-plugin' ),
|
|
353
|
+
'update_item' => __( 'Update Genre', 'my-plugin' ),
|
|
354
|
+
'add_new_item' => __( 'Add New Genre', 'my-plugin' ),
|
|
355
|
+
'new_item_name' => __( 'New Genre Name', 'my-plugin' ),
|
|
356
|
+
'menu_name' => __( 'Genres', 'my-plugin' ),
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
$args = array(
|
|
360
|
+
'labels' => $labels,
|
|
361
|
+
'hierarchical' => true,
|
|
362
|
+
'public' => true,
|
|
363
|
+
'show_ui' => true,
|
|
364
|
+
'show_admin_column' => true,
|
|
365
|
+
'query_var' => true,
|
|
366
|
+
'rewrite' => array( 'slug' => 'genre' ),
|
|
367
|
+
'show_in_rest' => true,
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
register_taxonomy( 'genre', array( 'book' ), $args );
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Workflow 3: Add Settings Page
|
|
375
|
+
|
|
376
|
+
### Step 1: Register Settings
|
|
377
|
+
|
|
378
|
+
```php
|
|
379
|
+
/**
|
|
380
|
+
* Register plugin settings
|
|
381
|
+
*/
|
|
382
|
+
public function register_settings() {
|
|
383
|
+
// Register setting
|
|
384
|
+
register_setting(
|
|
385
|
+
'my_plugin_options',
|
|
386
|
+
'my_plugin_option',
|
|
387
|
+
array(
|
|
388
|
+
'type' => 'string',
|
|
389
|
+
'sanitize_callback' => 'sanitize_text_field',
|
|
390
|
+
'default' => '',
|
|
391
|
+
)
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
// Add settings section
|
|
395
|
+
add_settings_section(
|
|
396
|
+
'my_plugin_section',
|
|
397
|
+
__( 'General Settings', 'my-plugin' ),
|
|
398
|
+
array( $this, 'section_callback' ),
|
|
399
|
+
'my-plugin'
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
// Add settings field
|
|
403
|
+
add_settings_field(
|
|
404
|
+
'my_plugin_field',
|
|
405
|
+
__( 'Option Name', 'my-plugin' ),
|
|
406
|
+
array( $this, 'field_callback' ),
|
|
407
|
+
'my-plugin',
|
|
408
|
+
'my_plugin_section'
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
add_action( 'admin_init', 'register_settings' );
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Section callback
|
|
415
|
+
*/
|
|
416
|
+
public function section_callback() {
|
|
417
|
+
echo '<p>' . esc_html__( 'Configure your plugin settings below.', 'my-plugin' ) . '</p>';
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Field callback
|
|
422
|
+
*/
|
|
423
|
+
public function field_callback() {
|
|
424
|
+
$value = get_option( 'my_plugin_option', '' );
|
|
425
|
+
echo '<input type="text" name="my_plugin_option" value="' . esc_attr( $value ) . '" class="regular-text" />';
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Security Best Practices
|
|
430
|
+
|
|
431
|
+
### Input Sanitization
|
|
432
|
+
|
|
433
|
+
```php
|
|
434
|
+
// Sanitize text field
|
|
435
|
+
$clean_text = sanitize_text_field( $_POST['field'] );
|
|
436
|
+
|
|
437
|
+
// Sanitize email
|
|
438
|
+
$clean_email = sanitize_email( $_POST['email'] );
|
|
439
|
+
|
|
440
|
+
// Sanitize URL
|
|
441
|
+
$clean_url = esc_url_raw( $_POST['url'] );
|
|
442
|
+
|
|
443
|
+
// Sanitize textarea
|
|
444
|
+
$clean_textarea = sanitize_textarea_field( $_POST['textarea'] );
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Output Escaping
|
|
448
|
+
|
|
449
|
+
```php
|
|
450
|
+
// Escape HTML
|
|
451
|
+
echo esc_html( $text );
|
|
452
|
+
|
|
453
|
+
// Escape attributes
|
|
454
|
+
echo '<div class="' . esc_attr( $class ) . '">';
|
|
455
|
+
|
|
456
|
+
// Escape URLs
|
|
457
|
+
echo '<a href="' . esc_url( $url ) . '">';
|
|
458
|
+
|
|
459
|
+
// Escape JavaScript
|
|
460
|
+
echo '<script>var data = ' . wp_json_encode( $data ) . ';</script>';
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Nonce Verification
|
|
464
|
+
|
|
465
|
+
```php
|
|
466
|
+
// Create nonce
|
|
467
|
+
wp_nonce_field( 'my_plugin_action', 'my_plugin_nonce' );
|
|
468
|
+
|
|
469
|
+
// Verify nonce
|
|
470
|
+
if ( ! isset( $_POST['my_plugin_nonce'] ) || ! wp_verify_nonce( $_POST['my_plugin_nonce'], 'my_plugin_action' ) ) {
|
|
471
|
+
wp_die( __( 'Security check failed', 'my-plugin' ) );
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Capability Checks
|
|
476
|
+
|
|
477
|
+
```php
|
|
478
|
+
// Check user capability
|
|
479
|
+
if ( ! current_user_can( 'manage_options' ) ) {
|
|
480
|
+
wp_die( __( 'You do not have sufficient permissions', 'my-plugin' ) );
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Best Practices
|
|
485
|
+
|
|
486
|
+
### DO
|
|
487
|
+
|
|
488
|
+
✅ Use WordPress coding standards
|
|
489
|
+
✅ Sanitize all input
|
|
490
|
+
✅ Escape all output
|
|
491
|
+
✅ Use nonces for form submissions
|
|
492
|
+
✅ Check user capabilities
|
|
493
|
+
✅ Use prepared statements for database queries
|
|
494
|
+
✅ Prefix all functions, classes, and database tables
|
|
495
|
+
✅ Use translation functions
|
|
496
|
+
✅ Enqueue scripts and styles properly
|
|
497
|
+
✅ Provide uninstall.php for cleanup
|
|
498
|
+
|
|
499
|
+
### DON'T
|
|
500
|
+
|
|
501
|
+
❌ Trust user input
|
|
502
|
+
❌ Use deprecated functions
|
|
503
|
+
❌ Modify WordPress core
|
|
504
|
+
❌ Use global namespace
|
|
505
|
+
❌ Hardcode database table names
|
|
506
|
+
❌ Include plugin functionality in themes
|
|
507
|
+
❌ Use `eval()` or similar dangerous functions
|
|
508
|
+
❌ Ignore error handling
|
|
509
|
+
❌ Skip documentation
|
|
510
|
+
|