├── .babelrc ├── .bin ├── copy.js ├── initial-rename.js ├── make-string.js └── replace-atrc.js ├── .gitignore ├── LICENSE.txt ├── README.txt ├── admin ├── class-admin.php └── index.php ├── assets ├── img │ ├── featured-image.png │ ├── logo-20-20.png │ ├── logo.png │ └── output-1.0.1.jpg └── library │ ├── atomic-css │ ├── atomic-rtl.css │ ├── atomic.css │ ├── atomic.min-rtl.css │ └── atomic.min.css │ └── fonts │ ├── open-sans.css │ └── open-sans │ ├── open-sans-v35-latin-300.woff2 │ ├── open-sans-v35-latin-500.woff2 │ ├── open-sans-v35-latin-600.woff2 │ ├── open-sans-v35-latin-700.woff2 │ ├── open-sans-v35-latin-800.woff2 │ └── open-sans-v35-latin-regular.woff2 ├── build ├── admin │ ├── index-rtl.css │ ├── index.asset.php │ ├── index.css │ └── index.js └── public │ ├── index-rtl.css │ ├── index.asset.php │ ├── index.css │ └── index.js ├── includes ├── api │ ├── class-api-settings.php │ ├── class-api.php │ └── index.php ├── class-activator.php ├── class-deactivator.php ├── class-i18n.php ├── class-include.php ├── class-loader.php ├── functions.php ├── index.php └── main.php ├── index.php ├── languages ├── js.pot └── wp-react-plugin-boilerplate.pot ├── package.json ├── process.md ├── public ├── class-public.php └── index.php ├── readme.md ├── src ├── _mixins.scss ├── admin │ ├── admin.scss │ ├── components │ │ ├── atoms │ │ │ ├── index.js │ │ │ └── save-settings.js │ │ ├── molecules │ │ │ ├── docs-title.js │ │ │ └── index.js │ │ └── organisms │ │ │ ├── admin-header.js │ │ │ └── index.js │ ├── index.js │ ├── pages │ │ ├── landing │ │ │ └── index.js │ │ └── settings │ │ │ ├── pages │ │ │ ├── advanced.js │ │ │ ├── index.js │ │ │ ├── settings1.js │ │ │ └── settings2.js │ │ │ └── routes.js │ └── routes.js ├── prefix-vars.scss └── public │ ├── index.js │ └── public.scss ├── uninstall.php └── wp-react-plugin-boilerplate.php /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@wordpress/babel-preset-default"], 3 | "plugins": [ 4 | [ 5 | "@wordpress/babel-plugin-makepot", 6 | { 7 | "output": "languages/js.pot" 8 | } 9 | ] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.bin/copy.js: -------------------------------------------------------------------------------- 1 | const ncp = require('ncp'); 2 | const rimraf = require('rimraf'); 3 | const path = require('path'); 4 | 5 | const source = process.cwd(); 6 | const destination = 'deploy'; 7 | 8 | const excludedFiles = [ 9 | destination, 10 | 'src', 11 | 'node_modules', 12 | '.git', 13 | '.bin', 14 | '.babelrc', 15 | '.gitignore', 16 | 'package.json', 17 | 'package-lock.json', 18 | '.map', 19 | 'js.pot', 20 | 'translation-js.php', 21 | 'info.md', 22 | ]; 23 | console.log('Excludes files and folder:'); 24 | const filterFunction = (file) => { 25 | const relativePath = path.relative(source, file); 26 | const fileName = path.basename(file); 27 | const fileExtension = path.extname(file); 28 | const isExcluded = 29 | excludedFiles.includes(fileName) || excludedFiles.includes(fileExtension); 30 | if (isExcluded) { 31 | console.log(`Excluded: ${fileName}`); 32 | } 33 | return !isExcluded; 34 | }; 35 | 36 | // Delete the destination directory 37 | rimraf(destination, (error) => { 38 | if (error) { 39 | console.error('Error occurred:', error); 40 | } else { 41 | // Copy the files and directories 42 | ncp(source, destination, { filter: filterFunction }, (error) => { 43 | if (error) { 44 | console.error('Error occurred:', error); 45 | } else { 46 | console.log('Files copied.'); 47 | console.log( 48 | "The plugin is built in the `deploy` folder for production. You can upload it to your WordPress site or to WordPress.org. Don't forget to check the files and folders, and test it thoroughly." 49 | ); 50 | } 51 | }); 52 | } 53 | }); 54 | -------------------------------------------------------------------------------- /.bin/initial-rename.js: -------------------------------------------------------------------------------- 1 | const replace = require('replace-in-file'); 2 | const glob = require('glob'); 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const { promisify } = require('util'); 6 | const renameAsync = promisify(fs.rename); 7 | 8 | const filePath = path.join(process.cwd(), '**/*.{js,php}'); 9 | 10 | const files = glob.sync(filePath, { 11 | ignore: ['**/node_modules/**'], 12 | }); 13 | 14 | const options = { 15 | files: files, 16 | from: [ 17 | /wp-react-plugin-boilerplate/g, 18 | /wp_react_plugin_boilerplate/g, 19 | /WP_REACT_PLUGIN_BOILERPLATE/g, 20 | /WP-REACT-PLUGIN-BOILERPLATE/g, 21 | /Wp-React-Plugin-Boilerplate/g, 22 | /Wp_React_Plugin_Boilerplate/g, 23 | /WpReactPluginBoilerplate/g, 24 | ], 25 | to: [ 26 | 'your-renamed-plugin',/******************** replace with your plugin details */ 27 | 'your_renamed_plugin', 28 | 'YOUR_RENAMED_PLUGIN', 29 | 'YOUR-RENAMED-PLUGIN', 30 | 'Your-Renamed-Plugin', 31 | 'Your_Renamed_Plugin', 32 | 'YourRenamedPlugin', 33 | ], 34 | verbose: true, 35 | dry: false, 36 | }; 37 | 38 | const renamedResults = []; 39 | async function renamePHPFiles() { 40 | const renamePromises = files 41 | .filter((file) => file.endsWith('.php')) 42 | .filter((file) => /wp-react-plugin-boilerplate/.test(file)) 43 | .map(async (file) => { 44 | const dir = path.dirname(file); 45 | const baseName = path.basename(file); 46 | const newBaseName = baseName.replace( 47 | /wp-react-plugin-boilerplate/gi, 48 | 'your-renamed-plugin'/******************** replace with your plugin details */ 49 | ); 50 | const newFileName = path.join(dir, newBaseName); 51 | 52 | try { 53 | const baseNameOriginalFile = path.basename(file); 54 | const baseNameNewFile = path.basename(newFileName); 55 | if (baseNameOriginalFile !== baseNameNewFile) { 56 | await renameAsync(file, newFileName); 57 | renamedResults.push({ 58 | from: file, 59 | to: newFileName, 60 | }); 61 | } 62 | } catch (error) { 63 | console.error(`Error renaming ${file}:`, error); 64 | } 65 | }); 66 | 67 | await Promise.all(renamePromises); 68 | } 69 | 70 | async function main() { 71 | try { 72 | const results = await replace(options); 73 | console.log('Replacement results:', results); 74 | await renamePHPFiles(); 75 | console.log(''); 76 | console.log('File renamed results:', renamedResults); 77 | 78 | } catch (error) { 79 | console.error('Error occurred:', error); 80 | } 81 | } 82 | 83 | main(); 84 | -------------------------------------------------------------------------------- /.bin/make-string.js: -------------------------------------------------------------------------------- 1 | /* TODO, not functional fully */ 2 | const glob = require('glob'); 3 | const path = require('path'); 4 | const { transformAsync } = require('@babel/core'); 5 | const fs = require('fs'); 6 | 7 | // let inputPath = path.join(process.cwd(), 'build/**/*.{js,php}'); 8 | let inputPath = path.join(process.cwd(), 'build/**/*.js'); 9 | let outputPath = path.join(process.cwd(), 'languages', 'translation-js.php'); 10 | 11 | // Replace backslashes with forward slashes for Windows compatibility 12 | inputPath = inputPath.replace(/\\/g, '/'); 13 | outputPath = outputPath.replace(/\\/g, '/'); 14 | 15 | // Print the input and output paths 16 | console.log('Input path:', inputPath); 17 | console.log('Output path:', outputPath); 18 | 19 | const files = glob.sync(inputPath); 20 | const pattern = /\(['"]([^'"]+)['"],\s*['"]wp-react-plugin-boilerplate['"]\)/g; 21 | 22 | let matches = []; 23 | let match; 24 | 25 | if (files) { 26 | files.map((file) => { 27 | // Check if the input files exist and are readable 28 | if (fs.existsSync(file)) { 29 | try { 30 | const data = fs.readFileSync(file, 'utf8'); 31 | while ((match = pattern.exec(data)) !== null) { 32 | matches.push(match[0]); 33 | } 34 | } catch (err) { 35 | console.error(`Error reading file: ${err}`); 36 | } 37 | } else { 38 | console.log(` ${file} Input file does not exist`); 39 | } 40 | }); 41 | } 42 | function uniqueArray(arr) { 43 | return [...new Set(arr)]; 44 | } 45 | 46 | if (matches) { 47 | const uniqueStrings = uniqueArray(matches); 48 | const translations = uniqueStrings.map((item) => { 49 | return `__${item}`; 50 | }); 51 | 52 | // Check if the output directory exists and is writable 53 | if (!fs.existsSync(path.dirname(outputPath))) { 54 | fs.mkdirSync(path.dirname(outputPath)); 55 | } 56 | 57 | // Write resultString to outputPath 58 | fs.writeFileSync(outputPath, ` 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | === WP React Plugin Boilerplate === 2 | Contributors: codersantosh 3 | Donate link: https://www.acmeit.org/ 4 | Tags: options, settings, react components, gutenberg block core editor 5 | Requires at least: 5.5 6 | Tested up to: 6.7 7 | Stable tag: 1.0.0 8 | Requires PHP: 5.6.20 9 | License: GPLv2 or later 10 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 11 | 12 | WP React Plugin Boilerplate - WordPress Setting via React and Rest API 13 | 14 | == Description == 15 | 16 | Add WordPress Setting via React and Rest API. 17 | Easily Create WordPress Plugin Setting or 18 | Add Setting While You are Doing Customization of Theme and Plugin. 19 | 20 | == Installation == 21 | 22 | 1. Upload the plugin files to the `/wp-content/plugins/wp-react-plugin-boilerplate` directory, or install the plugin through the WordPress plugins screen directly. 23 | 2. Activate the plugin through the 'Plugins' screen in WordPress 24 | 25 | == Development Process == 26 | 27 | Follow the following steps to install this starter boilerplate plugin: 28 | 29 | 1. Navigate to plugin files `/wp-content/plugins/wp-react-plugin-boilerplate`, open command app. 30 | 2. Run `npm install` command to install npm dependencies, wait sometimes to complete it. 31 | 3. Run `npm run start` command to initialize development of React JS, Development can be done any time. Use it in the development environment. 32 | 4. Run `npm run build` command to finalize the development and ready for production. The command creates production files. After building the production file move it to the production level. 33 | 34 | == React JS Source == 35 | 36 | Navigate to plugin files `/wp-content/plugins/wp-react-plugin-boilerplate/src` and start adding features 37 | 38 | == Changelog == 39 | 40 | = 1.0.0 = 41 | * Initial Release -------------------------------------------------------------------------------- /admin/class-admin.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Wp_React_Plugin_Boilerplate_Admin { 28 | 29 | /** 30 | * Menu info. 31 | * 32 | * @since 1.0.0 33 | * @access private 34 | * @var array $menu_info Admin menu information. 35 | */ 36 | private $menu_info; 37 | 38 | /** 39 | * Gets an instance of this object. 40 | * Prevents duplicate instances which avoid artefacts and improves performance. 41 | * 42 | * @static 43 | * @access public 44 | * @return object 45 | * @since 1.0.0 46 | */ 47 | public static function get_instance() { 48 | // Store the instance locally to avoid private static replication. 49 | static $instance = null; 50 | 51 | // Only run these methods if they haven't been ran previously. 52 | if ( null === $instance ) { 53 | $instance = new self(); 54 | } 55 | 56 | // Always return the instance. 57 | return $instance; 58 | } 59 | 60 | /** 61 | * Add Admin Page Menu page. 62 | * 63 | * @access public 64 | * 65 | * @since 1.0.0 66 | */ 67 | public function add_admin_menu() { 68 | 69 | $white_label = wp_react_plugin_boilerplate_include()->get_white_label(); 70 | $this->menu_info = $white_label['admin_menu_page']; 71 | 72 | add_menu_page( 73 | $this->menu_info['page_title'], 74 | $this->menu_info['menu_title'], 75 | 'manage_options', 76 | $this->menu_info['menu_slug'], 77 | array( $this, 'add_setting_root_div' ), 78 | $this->menu_info['icon_url'], 79 | $this->menu_info['position'], 80 | ); 81 | } 82 | 83 | /** 84 | * Check if current menu page. 85 | * 86 | * @access public 87 | * 88 | * @since 1.0.0 89 | * @return boolean ture if current menu page else false. 90 | */ 91 | public function is_menu_page() { 92 | $screen = get_current_screen(); 93 | $admin_scripts_bases = array( 'toplevel_page_' . WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME ); 94 | if ( ! ( isset( $screen->base ) && in_array( $screen->base, $admin_scripts_bases, true ) ) ) { 95 | return false; 96 | } 97 | return true; 98 | } 99 | 100 | /** 101 | * Add class "at-has-hdr-stky". 102 | * 103 | * @access public 104 | * @since 1.0.0 105 | * @param string $classes a space-separated string of class names. 106 | * @return string $classes with added class if confition meet. 107 | */ 108 | public function add_has_sticky_header( $classes ) { 109 | 110 | if ( ! $this->is_menu_page() ) { 111 | return $classes; 112 | } 113 | 114 | return $classes . ' at-has-hdr-stky '; 115 | } 116 | 117 | /** 118 | * Add Root Div For React. 119 | * 120 | * @access public 121 | * 122 | * @since 1.0.0 123 | */ 124 | public function add_setting_root_div() { 125 | echo '
'; 126 | } 127 | 128 | /** 129 | * Register the CSS/JavaScript Resources for the admin area. 130 | * 131 | * @access public 132 | * Use Condition to Load it Only When it is Necessary 133 | * 134 | * @since 1.0.0 135 | */ 136 | public function enqueue_resources() { 137 | 138 | if ( ! $this->is_menu_page() ) { 139 | return; 140 | } 141 | 142 | /* Atomic CSS */ 143 | wp_enqueue_style( 'atomic' ); 144 | wp_style_add_data( 'atomic', 'rtl', 'replace' ); 145 | 146 | /*Scripts dependency files*/ 147 | $deps_file = WP_REACT_PLUGIN_BOILERPLATE_PATH . 'build/admin/index.asset.php'; 148 | 149 | /*Fallback dependency array*/ 150 | $dependency = array(); 151 | $version = WP_REACT_PLUGIN_BOILERPLATE_VERSION; 152 | 153 | /*Set dependency and version*/ 154 | if ( file_exists( $deps_file ) ) { 155 | $deps_file = require $deps_file; 156 | $dependency = $deps_file['dependencies']; 157 | $version = $deps_file['version']; 158 | } 159 | 160 | wp_enqueue_script( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_URL . 'build/admin/index.js', $dependency, $version, true ); 161 | 162 | wp_enqueue_style( 'google-fonts-open-sans', WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/library/fonts/open-sans.css', '', $version ); 163 | wp_enqueue_style( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_URL . 'build/admin/index.css', array( 'wp-components' ), $version ); 164 | wp_style_add_data( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 'rtl', 'replace' ); 165 | 166 | /* Localize */ 167 | $localize = apply_filters( 168 | 'wp_react_plugin_boilerplate_admin_localize', 169 | array( 170 | 'version' => $version, 171 | 'root_id' => WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 172 | 'nonce' => wp_create_nonce( 'wp_rest' ), 173 | 'store' => WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 174 | 'rest_url' => get_rest_url(), 175 | 'white_label' => wp_react_plugin_boilerplate_include()->get_white_label(), 176 | ) 177 | ); 178 | 179 | wp_set_script_translations( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME ); 180 | wp_localize_script( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 'WpReactPluginBoilerplateLocalize', $localize ); 181 | } 182 | 183 | /** 184 | * Get settings schema 185 | * Schema: http://json-schema.org/draft-04/schema# 186 | * 187 | * Add your own settings fields here 188 | * 189 | * @access public 190 | * 191 | * @since 1.0.0 192 | * 193 | * @return array settings schema for this plugin. 194 | */ 195 | public function get_settings_schema() { 196 | $setting_properties = apply_filters( 197 | 'wp_react_plugin_boilerplate_options_properties', 198 | array( 199 | /*Settings -> Settings1*/ 200 | 'setting1' => array( 201 | 'type' => 'string', 202 | ), 203 | 'setting2' => array( 204 | 'type' => 'string', 205 | ), 206 | /*Settings -> Settings2*/ 207 | 'setting3' => array( 208 | 'type' => 'boolean', 209 | ), 210 | 'setting4' => array( 211 | 'type' => 'boolean', 212 | ), 213 | 'setting5' => array( 214 | 'type' => 'string', 215 | 'sanitize_callback' => 'sanitize_key', 216 | ), 217 | /*Settings -> Advanced*/ 218 | 'deleteAll' => array( 219 | 'type' => 'boolean', 220 | ), 221 | ), 222 | ); 223 | 224 | return array( 225 | 'type' => 'object', 226 | 'properties' => $setting_properties, 227 | ); 228 | } 229 | 230 | /** 231 | * Register settings. 232 | * Common callback function of rest_api_init and admin_init 233 | * 234 | * @since 1.0.0 235 | * 236 | * @return void 237 | */ 238 | public function register_settings() { 239 | $defaults = wp_react_plugin_boilerplate_default_options(); 240 | 241 | register_setting( 242 | 'wp_react_plugin_boilerplate_settings_group', 243 | WP_REACT_PLUGIN_BOILERPLATE_OPTION_NAME, 244 | array( 245 | 'type' => 'object', 246 | 'default' => $defaults, 247 | 'show_in_rest' => array( 248 | 'schema' => $this->get_settings_schema(), 249 | ), 250 | ) 251 | ); 252 | } 253 | 254 | /** 255 | * Add plugin menu items. 256 | * 257 | * @access public 258 | * 259 | * @since 1.0.0 260 | * @param string[] $actions An array of plugin action links. By default this can include 261 | * 'activate', 'deactivate', and 'delete'. With Multisite active 262 | * this can also include 'network_active' and 'network_only' items. 263 | * @param string $plugin_file Path to the plugin file relative to the plugins directory. 264 | * @param array $plugin_data An array of plugin data. See get_plugin_data() 265 | * and the {@see 'plugin_row_meta'} filter for the list 266 | * of possible values. 267 | * @param string $context The plugin context. By default this can include 'all', 268 | * 'active', 'inactive', 'recently_activated', 'upgrade', 269 | * 'mustuse', 'dropins', and 'search'. 270 | * @return array settings schema for this plugin. 271 | */ 272 | public function add_plugin_links( $actions, $plugin_file, $plugin_data, $context ) { 273 | $actions[] = '' . esc_html__( 'Settings', 'wp-react-plugin-boilerplate' ) . ''; 274 | return $actions; 275 | } 276 | } 277 | 278 | if ( ! function_exists( 'wp_react_plugin_boilerplate_admin' ) ) { 279 | /** 280 | * Return instance of Wp_React_Plugin_Boilerplate_Admin class 281 | * 282 | * @since 1.0.0 283 | * 284 | * @return Wp_React_Plugin_Boilerplate_Admin 285 | */ 286 | function wp_react_plugin_boilerplate_admin() {//phpcs:ignore 287 | return Wp_React_Plugin_Boilerplate_Admin::get_instance(); 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /admin/index.php: -------------------------------------------------------------------------------- 1 | array('lodash', 'react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '4e0ac48cf38e46e9c7f7'); 2 | -------------------------------------------------------------------------------- /build/public/index-rtl.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /build/public/index.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '7b36695cf4db7884e53f'); 2 | -------------------------------------------------------------------------------- /build/public/index.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /build/public/index.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";console.log("Hello from public")}(); -------------------------------------------------------------------------------- /includes/api/class-api-settings.php: -------------------------------------------------------------------------------- 1 | 22 | * 23 | * @see Wp_React_Plugin_Boilerplate_Api 24 | */ 25 | if ( ! class_exists( 'Wp_React_Plugin_Boilerplate_Api_Settings' ) ) { 26 | 27 | /** 28 | * Wp_React_Plugin_Boilerplate_Api_Settings 29 | * 30 | * @see WP_REST_Settings_Controller 31 | * @package Wp_React_Plugin_Boilerplate 32 | * @since 1.0.0 33 | */ 34 | class Wp_React_Plugin_Boilerplate_Api_Settings extends Wp_React_Plugin_Boilerplate_Api { 35 | 36 | /** 37 | * Initialize the class and set up actions. 38 | * 39 | * @access public 40 | * @return void 41 | */ 42 | public function run() { 43 | $this->type = 'wp_react_plugin_boilerplate_api_settings'; 44 | $this->rest_base = 'settings'; 45 | 46 | /*Custom Rest Routes*/ 47 | add_action( 'rest_api_init', array( $this, 'register_routes' ) ); 48 | } 49 | 50 | /** 51 | * Register REST API route. 52 | * 53 | * @since 1.0.0 54 | */ 55 | public function register_routes() { 56 | $namespace = $this->namespace . $this->version; 57 | 58 | register_rest_route( 59 | $namespace, 60 | '/' . $this->rest_base, 61 | array( 62 | array( 63 | 'methods' => WP_REST_Server::READABLE, 64 | 'callback' => array( $this, 'get_item' ), 65 | 'args' => array(), 66 | 'permission_callback' => array( $this, 'get_item_permissions_check' ), 67 | ), 68 | array( 69 | 'methods' => WP_REST_Server::EDITABLE, 70 | 'callback' => array( $this, 'update_item' ), 71 | 'args' => rest_get_endpoint_args_for_schema( $this->get_item_schema(), WP_REST_Server::EDITABLE ), 72 | 'permission_callback' => array( $this, 'get_item_permissions_check' ), 73 | ), 74 | 'schema' => array( $this, 'get_public_item_schema' ), 75 | ) 76 | ); 77 | } 78 | 79 | /** 80 | * Checks if a given request has access to read and manage settings. 81 | * 82 | * @since 1.0.0 83 | * 84 | * @param WP_REST_Request $request Full details about the request. 85 | * @return bool True if the request has read access for the item, otherwise false. 86 | */ 87 | public function get_item_permissions_check( $request ) { 88 | return current_user_can( 'manage_options' ); 89 | } 90 | 91 | /** 92 | * Retrieves the settings. 93 | * 94 | * @since 1.0.0 95 | * 96 | * @param WP_REST_Request $request Full details about the request. 97 | * @return array|WP_Error Array on success, or WP_Error object on failure. 98 | */ 99 | public function get_item( $request ) { 100 | $response = array(); 101 | 102 | $saved_options = wp_react_plugin_boilerplate_get_options(); 103 | 104 | $schema = $this->get_registered_schema(); 105 | 106 | $response = $this->prepare_value( $saved_options, $schema ); 107 | 108 | return $response; 109 | } 110 | 111 | /** 112 | * Prepares a value for output based off a schema array. 113 | * 114 | * @since 1.0.0 115 | * 116 | * @param mixed $value Value to prepare. 117 | * @param array $schema Schema to match. 118 | * @return mixed The prepared value. 119 | */ 120 | protected function prepare_value( $value, $schema ) { 121 | 122 | $sanitized_value = rest_sanitize_value_from_schema( $value, $schema ); 123 | 124 | return $sanitized_value; 125 | } 126 | 127 | /** 128 | * Updates settings. 129 | * 130 | * @since 1.0.0 131 | * 132 | * @param WP_REST_Request $request Full details about the request. 133 | * @return array|WP_Error Array on success, or error object on failure. 134 | */ 135 | public function update_item( $request ) { 136 | $schema = $this->get_registered_schema(); 137 | 138 | $params = $request->get_params(); 139 | 140 | if ( is_wp_error( rest_validate_value_from_schema( $params, $schema ) ) ) { 141 | return new WP_Error( 142 | 'rest_invalid_stored_value', 143 | /* translators: %s: Property name. */ 144 | sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.', 'wp-react-plugin-boilerplate' ), WP_REACT_PLUGIN_BOILERPLATE_OPTION_NAME ), 145 | array( 'status' => 500 ) 146 | ); 147 | } 148 | 149 | $sanitized_options = $this->prepare_value( $params, $schema ); 150 | wp_react_plugin_boilerplate_update_options( $sanitized_options ); 151 | 152 | return $this->get_item( $request ); 153 | } 154 | 155 | /** 156 | * Retrieves all of the registered options for the Settings API. 157 | * 158 | * @since 1.0.0 159 | * 160 | * @return array Array of registered options. 161 | */ 162 | protected function get_registered_schema() { 163 | // Use a static variable to cache the schema. 164 | static $cached_schema = null; 165 | 166 | // If the schema is already cached, return it. 167 | if ( null !== $cached_schema ) { 168 | return $cached_schema; 169 | } 170 | 171 | // If not cached, fetch the value and cache it. 172 | $schema = wp_react_plugin_boilerplate_admin()->get_settings_schema(); 173 | 174 | // Cache the schema in the static variable. 175 | $cached_schema = $schema; 176 | 177 | return $schema; 178 | } 179 | 180 | /** 181 | * Retrieves the site setting schema, conforming to JSON Schema. 182 | * 183 | * @since 1.0.0 184 | * 185 | * @return array Item schema data. 186 | */ 187 | public function get_item_schema() { 188 | $schema = array( 189 | '$schema' => 'http://json-schema.org/draft-04/schema#', 190 | 'title' => $this->type, 191 | 'type' => 'object', 192 | 'properties' => $this->get_registered_schema()['properties'], 193 | ); 194 | 195 | /** 196 | * Filters the item's schema. 197 | * 198 | * @param array $schema Item schema data. 199 | */ 200 | $schema = apply_filters( "rest_{$this->type}_item_schema", $schema ); 201 | 202 | $this->schema = $schema; 203 | 204 | return $this->add_additional_fields_schema( $this->schema ); 205 | } 206 | 207 | /** 208 | * Gets an instance of this object. 209 | * Prevents duplicate instances which avoid artefacts and improves performance. 210 | * 211 | * @static 212 | * @access public 213 | * @return object 214 | * @since 1.0.0 215 | */ 216 | public static function get_instance() { 217 | // Store the instance locally to avoid private static replication. 218 | static $instance = null; 219 | 220 | // Only run these methods if they haven't been ran previously. 221 | if ( null === $instance ) { 222 | $instance = new self(); 223 | } 224 | 225 | // Always return the instance. 226 | return $instance; 227 | } 228 | } 229 | } 230 | 231 | /** 232 | * Return instance of Wp_React_Plugin_Boilerplate_Api_Settings class 233 | * 234 | * @since 1.0.0 235 | * 236 | * @return Wp_React_Plugin_Boilerplate_Api_Settings 237 | */ 238 | function wp_react_plugin_boilerplate_api_settings() { //phpcs:ignore 239 | return Wp_React_Plugin_Boilerplate_Api_Settings::get_instance(); 240 | } 241 | wp_react_plugin_boilerplate_api_settings()->run(); 242 | -------------------------------------------------------------------------------- /includes/api/class-api.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | if ( ! class_exists( 'Wp_React_Plugin_Boilerplate_Api' ) ) { 27 | 28 | /** 29 | * Wp_React_Plugin_Boilerplate_Api 30 | * 31 | * @package Wp_React_Plugin_Boilerplate 32 | * @since 1.0.1 33 | */ 34 | class Wp_React_Plugin_Boilerplate_Api extends WP_REST_Controller { 35 | 36 | /** 37 | * Rest route namespace. 38 | * 39 | * @var Wp_React_Plugin_Boilerplate_Api 40 | */ 41 | public $namespace = 'wp-react-plugin-boilerplate/'; 42 | 43 | /** 44 | * Rest route version. 45 | * 46 | * @var Wp_React_Plugin_Boilerplate_Api 47 | */ 48 | public $version = 'v1'; 49 | 50 | /** 51 | * Whether the controller supports batching. 52 | * 53 | * @since 1.0.0 54 | * @var array 55 | */ 56 | protected $allow_batch = array( 'v1' => true ); 57 | 58 | /** 59 | * Table name. 60 | * 61 | * @var string 62 | */ 63 | public $type; 64 | 65 | /** 66 | * Constructor 67 | * 68 | * @since 1.0.0 69 | */ 70 | public function __construct() {} 71 | 72 | /** 73 | * Initialize the class 74 | */ 75 | public function run() { 76 | /*Custom Rest Routes*/ 77 | add_action( 'rest_api_init', array( $this, 'register_routes' ) ); 78 | } 79 | 80 | /** 81 | * Gets an instance of this object. 82 | * Prevents duplicate instances which avoid artefacts and improves performance. 83 | * 84 | * @static 85 | * @access public 86 | * @return object 87 | * @since 1.0.1 88 | */ 89 | public static function get_instance() { 90 | // Store the instance locally to avoid private static replication. 91 | static $instance = null; 92 | 93 | // Only run these methods if they haven't been ran previously. 94 | if ( null === $instance ) { 95 | 96 | $instance = new self(); 97 | } 98 | 99 | // Always return the instance. 100 | return $instance; 101 | } 102 | 103 | /** 104 | * Throw error on object clone 105 | * 106 | * The whole idea of the singleton design pattern is that there is a single 107 | * object therefore, we don't want the object to be cloned. 108 | * 109 | * @access public 110 | * @return void 111 | * @since 1.0.0 112 | */ 113 | public function __clone() { 114 | // Cloning instances of the class is forbidden. 115 | _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'wp-react-plugin-boilerplate' ), '1.0.0' ); 116 | } 117 | 118 | /** 119 | * Disable unserializing of the class 120 | * 121 | * @access public 122 | * @return void 123 | * @since 1.0.0 124 | */ 125 | public function __wakeup() { 126 | // Unserializing instances of the class is forbidden. 127 | _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'wp-react-plugin-boilerplate' ), '1.0.0' ); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /includes/api/index.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Wp_React_Plugin_Boilerplate_Activator { 28 | 29 | /** 30 | * Short Description. (use period) 31 | * 32 | * Long Description. 33 | * 34 | * @since 1.0.0 35 | */ 36 | public static function activate() { 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /includes/class-deactivator.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Wp_React_Plugin_Boilerplate_Deactivator { 28 | 29 | /** 30 | * Fired during plugin deactivation. 31 | * 32 | * Removing options and all data related to plugin if user select remove data on deactivate. 33 | * 34 | * @since 1.0.0 35 | */ 36 | public static function deactivate() { 37 | if ( wp_react_plugin_boilerplate_get_options( 'deleteAll' ) ) { 38 | delete_option( WP_REACT_PLUGIN_BOILERPLATE_OPTION_NAME ); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /includes/class-i18n.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | class Wp_React_Plugin_Boilerplate_I18n { 31 | 32 | /** 33 | * Load the plugin text domain for translation. 34 | * 35 | * @since 1.0.0 36 | */ 37 | public function load_plugin_textdomain() { 38 | 39 | load_plugin_textdomain( 40 | 'wp-react-plugin-boilerplate', 41 | false, 42 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /includes/class-include.php: -------------------------------------------------------------------------------- 1 | 30 | */ 31 | class Wp_React_Plugin_Boilerplate_Include { 32 | 33 | /** 34 | * Gets an instance of this object. 35 | * Prevents duplicate instances which avoid artefacts and improves performance. 36 | * 37 | * @static 38 | * @access public 39 | * @return object 40 | * @since 1.0.0 41 | */ 42 | public static function get_instance() { 43 | // Store the instance locally to avoid private static replication. 44 | static $instance = null; 45 | 46 | // Only run these methods if they haven't been ran previously. 47 | if ( null === $instance ) { 48 | $instance = new self(); 49 | } 50 | 51 | // Always return the instance. 52 | return $instance; 53 | } 54 | /** 55 | * Get the settings with caching. 56 | * 57 | * @access public 58 | * @param string $key optional meta key. 59 | * @return array|null 60 | */ 61 | public function get_settings( $key = '' ) { 62 | static $cache = null; 63 | if ( ! $cache ) { 64 | $cache = wp_react_plugin_boilerplate_get_options(); 65 | } 66 | if ( ! empty( $key ) ) { 67 | return isset( $cache[ $key ] ) ? $cache[ $key ] : false; 68 | } 69 | 70 | return $cache; 71 | } 72 | 73 | /** 74 | * Get options related to white label. 75 | * 76 | * @access public 77 | * @return array|null 78 | */ 79 | public function get_white_label() { 80 | static $cache = null; 81 | if ( ! $cache ) { 82 | $cache = wp_react_plugin_boilerplate_get_white_label(); 83 | } 84 | 85 | return $cache; 86 | } 87 | 88 | /** 89 | * Register scripts and styles 90 | * 91 | * @since 1.0.0 92 | * @access public 93 | * @return void 94 | */ 95 | public function register_scripts_and_styles() { 96 | /* Atomic css */ 97 | wp_register_style( 'atomic', WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/library/atomic-css/atomic.min.css', array(), WP_REACT_PLUGIN_BOILERPLATE_VERSION ); 98 | } 99 | } 100 | 101 | if ( ! function_exists( 'wp_react_plugin_boilerplate_include' ) ) { 102 | /** 103 | * Return instance of Wp_React_Plugin_Boilerplate_Include class 104 | * 105 | * @since 1.0.0 106 | * 107 | * @return Wp_React_Plugin_Boilerplate_Include 108 | */ 109 | function wp_react_plugin_boilerplate_include() {//phpcs:ignore 110 | return Wp_React_Plugin_Boilerplate_Include::get_instance(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /includes/class-loader.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Wp_React_Plugin_Boilerplate_Loader { 28 | 29 | /** 30 | * The array of actions registered with WordPress. 31 | * 32 | * @since 1.0.0 33 | * @access protected 34 | * @var array $actions The actions registered with WordPress to fire when the plugin loads. 35 | */ 36 | protected $actions; 37 | 38 | /** 39 | * The array of filters registered with WordPress. 40 | * 41 | * @since 1.0.0 42 | * @access protected 43 | * @var array $filters The filters registered with WordPress to fire when the plugin loads. 44 | */ 45 | protected $filters; 46 | 47 | /** 48 | * Initialize the collections used to maintain the actions and filters. 49 | * 50 | * @since 1.0.0 51 | */ 52 | public function __construct() { 53 | 54 | $this->actions = array(); 55 | $this->filters = array(); 56 | } 57 | 58 | /** 59 | * Add a new action to the collection to be registered with WordPress. 60 | * 61 | * @since 1.0.0 62 | * @param string $hook The name of the WordPress action that is being registered. 63 | * @param object $component A reference to the instance of the object on which the action is defined. 64 | * @param string $callback The name of the function definition on the $component. 65 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10. 66 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. 67 | */ 68 | public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 69 | $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args ); 70 | } 71 | 72 | /** 73 | * Add a new filter to the collection to be registered with WordPress. 74 | * 75 | * @since 1.0.0 76 | * @param string $hook The name of the WordPress filter that is being registered. 77 | * @param object $component A reference to the instance of the object on which the filter is defined. 78 | * @param string $callback The name of the function definition on the $component. 79 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10. 80 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. 81 | */ 82 | public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 83 | $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); 84 | } 85 | 86 | /** 87 | * A utility function that is used to register the actions and hooks into a single 88 | * collection. 89 | * 90 | * @since 1.0.0 91 | * @access private 92 | * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). 93 | * @param string $hook The name of the WordPress filter that is being registered. 94 | * @param object $component A reference to the instance of the object on which the filter is defined. 95 | * @param string $callback The name of the function definition on the $component. 96 | * @param int $priority The priority at which the function should be fired. 97 | * @param int $accepted_args The number of arguments that should be passed to the $callback. 98 | * @return array The collection of actions and filters registered with WordPress. 99 | */ 100 | private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) { 101 | 102 | $hooks[] = array( 103 | 'hook' => $hook, 104 | 'component' => $component, 105 | 'callback' => $callback, 106 | 'priority' => $priority, 107 | 'accepted_args' => $accepted_args, 108 | ); 109 | 110 | return $hooks; 111 | } 112 | 113 | /** 114 | * Register the filters and actions with WordPress. 115 | * 116 | * @since 1.0.0 117 | */ 118 | public function run() { 119 | 120 | foreach ( $this->filters as $hook ) { 121 | add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 122 | } 123 | 124 | foreach ( $this->actions as $hook ) { 125 | add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /includes/functions.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | // Exit if accessed directly. 11 | if ( ! defined( 'ABSPATH' ) ) { 12 | exit; 13 | } 14 | 15 | 16 | if ( ! function_exists( 'wp_react_plugin_boilerplate_default_options' ) ) : 17 | /** 18 | * Get the Plugin Default Options. 19 | * 20 | * @since 1.0.0 21 | * 22 | * @return array Default Options 23 | * 24 | * @author codersantosh 25 | */ 26 | function wp_react_plugin_boilerplate_default_options() { 27 | $default_theme_options = array( 28 | 'setting1' => esc_html__( 'Default Setting 1', 'wp-react-plugin-boilerplate' ), 29 | 'setting2' => esc_html__( 'Default Setting 2', 'wp-react-plugin-boilerplate' ), 30 | 'setting3' => false, 31 | 'setting4' => true, 32 | 'setting5' => 'option-1', 33 | 'deleteAll' => false, 34 | ); 35 | 36 | return apply_filters( 'wp_react_plugin_boilerplate_default_options', $default_theme_options ); 37 | } 38 | endif; 39 | 40 | if ( ! function_exists( 'wp_react_plugin_boilerplate_get_options' ) ) : 41 | 42 | /** 43 | * Get the Plugin Saved Options. 44 | * 45 | * @since 1.0.0 46 | * 47 | * @param string $key optional option key. 48 | * 49 | * @return mixed All Options Array Or Options Value 50 | * 51 | * @author codersantosh 52 | */ 53 | function wp_react_plugin_boilerplate_get_options( $key = '' ) { 54 | $options = get_option( WP_REACT_PLUGIN_BOILERPLATE_OPTION_NAME ); 55 | 56 | $default_options = wp_react_plugin_boilerplate_default_options(); 57 | 58 | if ( ! empty( $key ) ) { 59 | if ( isset( $options[ $key ] ) ) { 60 | return $options[ $key ]; 61 | } 62 | return isset( $default_options[ $key ] ) ? $default_options[ $key ] : false; 63 | } else { 64 | if ( ! is_array( $options ) ) { 65 | $options = array(); 66 | } 67 | 68 | return array_merge( $default_options, $options ); 69 | } 70 | } 71 | endif; 72 | 73 | if ( ! function_exists( 'wp_react_plugin_boilerplate_update_options' ) ) : 74 | /** 75 | * Update the Plugin Options. 76 | * 77 | * @since 1.0.0 78 | * 79 | * @param string|array $key_or_data array of options or single option key. 80 | * @param string $val value of option key. 81 | * 82 | * @return mixed All Options Array Or Options Value 83 | * 84 | * @author codersantosh 85 | */ 86 | function wp_react_plugin_boilerplate_update_options( $key_or_data, $val = '' ) { 87 | if ( is_string( $key_or_data ) ) { 88 | $options = wp_react_plugin_boilerplate_get_options(); 89 | $options[ $key_or_data ] = $val; 90 | } else { 91 | $options = $key_or_data; 92 | } 93 | update_option( WP_REACT_PLUGIN_BOILERPLATE_OPTION_NAME, $options ); 94 | } 95 | endif; 96 | 97 | 98 | if ( ! function_exists( 'wp_react_plugin_boilerplate_file_system' ) ) { 99 | /** 100 | * 101 | * WordPress file system wrapper 102 | * 103 | * @since 1.0.0 104 | * 105 | * @return string|WP_Error directory path or WP_Error object if no permission 106 | * 107 | * @author codersantosh 108 | */ 109 | function wp_react_plugin_boilerplate_file_system() { 110 | global $wp_filesystem; 111 | if ( ! $wp_filesystem ) { 112 | require_once ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'file.php'; 113 | } 114 | 115 | WP_Filesystem(); 116 | return $wp_filesystem; 117 | } 118 | } 119 | 120 | if ( ! function_exists( 'wp_react_plugin_boilerplate_parse_changelog' ) ) { 121 | 122 | /** 123 | * Parse changelog 124 | * 125 | * @since 1.0.0 126 | * @return string 127 | * 128 | * @author codersantosh 129 | */ 130 | function wp_react_plugin_boilerplate_parse_changelog() { 131 | 132 | $wp_filesystem = wp_react_plugin_boilerplate_file_system(); 133 | 134 | $changelog_file = apply_filters( 'wp_react_plugin_boilerplate_changelog_file', WP_REACT_PLUGIN_BOILERPLATE_PATH . 'readme.txt' ); 135 | 136 | /*Check if the changelog file exists and is readable.*/ 137 | if ( ! $changelog_file || ! is_readable( $changelog_file ) ) { 138 | return ''; 139 | } 140 | 141 | $content = $wp_filesystem->get_contents( $changelog_file ); 142 | 143 | if ( ! $content ) { 144 | return ''; 145 | } 146 | 147 | $matches = null; 148 | $regexp = '~==\s*Changelog\s*==(.*)($)~Uis'; 149 | $changelog = ''; 150 | 151 | if ( preg_match( $regexp, $content, $matches ) ) { 152 | $changes = explode( '\r\n', trim( $matches[1] ) ); 153 | 154 | foreach ( $changes as $index => $line ) { 155 | $changelog .= wp_kses_post( preg_replace( '~(=\s*Version\s*(\d+(?:\.\d+)+)\s*=|$)~Uis', '', $line ) ); 156 | } 157 | } 158 | 159 | return wp_kses_post( $changelog ); 160 | } 161 | } 162 | 163 | if ( ! function_exists( 'wp_react_plugin_boilerplate_get_white_label' ) ) : 164 | /** 165 | * Get white label options for this plugin. 166 | * 167 | * @since 1.0.0 168 | * @param string $key optional option key. 169 | * @return mixed All Options Array Or Options Value 170 | * @author codersantosh 171 | */ 172 | function wp_react_plugin_boilerplate_get_white_label( $key = '' ) { 173 | $plugin_name = apply_filters( 174 | 'wp_react_plugin_boilerplate_white_label_plugin_name', 175 | esc_html__( 'WP React Plugin Boilerplate', 'wp-react-plugin-boilerplate' ) 176 | ); 177 | 178 | $options = apply_filters( 179 | 'wp_react_plugin_boilerplate_white_label', 180 | array( 181 | 'admin_menu_page' => array( 182 | 'page_title' => esc_html__( 'ReactJs Settings Page', 'wp-react-plugin-boilerplate' ), 183 | 'menu_title' => esc_html__( 'ReactJs Settings', 'wp-react-plugin-boilerplate' ), 184 | 'menu_slug' => WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 185 | 'icon_url' => WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/img/logo-20-20.png', 186 | 'position' => null, 187 | ), 188 | 'dashboard' => array( 189 | 'logo' => WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/img/logo.png', 190 | 'notice' => sprintf( 191 | /* translators: %s is the plugin name */ 192 | esc_html__( 193 | 'Congratulations on choosing the %s for creating your plugin. We recommend taking a few minutes to read the following information on how the plugin works. Please read it carefully to fully understand the capabilities of the plugin and how to use them effectively.', 194 | 'wp-react-plugin-boilerplate' 195 | ), 196 | $plugin_name 197 | ), 198 | ), 199 | 'landingPage' => array( 200 | 'banner' => array( 201 | 'heading' => $plugin_name, 202 | 'leadText' => sprintf( 203 | /* translators: %s is the plugin name */ 204 | esc_html__( 205 | 'Congratulations! You have successfully installed %s and it is ready for customization. Feel free to add/edit any files.', 206 | 'wp-react-plugin-boilerplate' 207 | ), 208 | $plugin_name 209 | ), 210 | 'normalText' => sprintf( 211 | /* translators: %s is the plugin name */ 212 | esc_html__( 213 | 'If you have any questions or need assistance, please do not hesitate to contact us for support. The %s plugin caters to WordPress developers and designers seeking to quickly start developing WordPress plugins in a modern way using ReactJS, Rest API.', 214 | 'wp-react-plugin-boilerplate' 215 | ), 216 | $plugin_name, 217 | ), 218 | 'buttons' => array( 219 | array( 220 | 'icon' => '', 221 | 'text' => esc_html__( 'Get started', 'wp-react-plugin-boilerplate' ), 222 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 223 | 'variant' => 'primary', 224 | ), 225 | array( 226 | 'icon' => '', 227 | 'text' => esc_html__( 'Docmentation', 'wp-react-plugin-boilerplate' ), 228 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 229 | 'variant' => 'outline-primary', 230 | ), 231 | array( 232 | 'icon' => '', 233 | 'text' => esc_html__( 'Get support', 'wp-react-plugin-boilerplate' ), 234 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 235 | 'variant' => 'secondary', 236 | 237 | ), 238 | ), 239 | 'image' => WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/img/featured-image.png', 240 | 241 | ), 242 | 'identity' => array( 243 | 'logo' => WP_REACT_PLUGIN_BOILERPLATE_URL . 'assets/img/logo.png', 244 | 'title' => $plugin_name, 245 | 'buttons' => array( 246 | array( 247 | 'text' => esc_html__( 'Visit site', 'wp-react-plugin-boilerplate' ), 248 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 249 | 'variant' => 'primary', 250 | ), 251 | array( 252 | 'text' => esc_html__( 'Get Support', 'wp-react-plugin-boilerplate' ), 253 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 254 | 'variant' => 'light', 255 | ), 256 | ), 257 | ), 258 | 'contact' => array( 259 | 'title' => esc_html__( 'Contact Information', 'wp-react-plugin-boilerplate' ), 260 | 'info' => array( 261 | array( 262 | 'icon' => '', 263 | 'title' => esc_html__( 'Support', 'wp-react-plugin-boilerplate' ), 264 | 'text' => esc_html__( 'Get Support', 'wp-react-plugin-boilerplate' ), 265 | 'url' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 266 | 'variant' => 'link', 267 | ), 268 | array( 269 | 'icon' => '', 270 | 'title' => esc_html__( 'Email', 'wp-react-plugin-boilerplate' ), 271 | 'text' => esc_html__( 'codersantosh@gmail.com', 'wp-react-plugin-boilerplate' ), 272 | 'url' => 'mailto:codersantosh@icloud.com', 273 | 'variant' => 'link', 274 | ), 275 | array( 276 | 'icon' => '', 277 | 'title' => esc_html__( 'Location', 'wp-react-plugin-boilerplate' ), 278 | 'text' => esc_html__( 'Kathmandu, Nepal', 'wp-react-plugin-boilerplate' ), 279 | ), 280 | ), 281 | 'social' => array( 282 | array( 283 | 'icon' => '', 284 | 'url' => 'https://profiles.wordpress.org/codersantosh/', 285 | 'variant' => 'outline-primary', 286 | ), 287 | array( 288 | 'icon' => '', 289 | 'url' => 'https://github.com/codersantosh', 290 | 'variant' => 'outline-primary', 291 | ), 292 | array( 293 | 'icon' => '', 294 | 'url' => 'https://twitter.com/codersantosh', 295 | 'variant' => 'outline-primary', 296 | ), 297 | ), 298 | ), 299 | 'bannerColumns' => array( 300 | array( 301 | 'icon' => '', 302 | 'title' => esc_html__( 'Activate Plugin', 'wp-react-plugin-boilerplate' ), 303 | ), 304 | array( 305 | 'icon' => '', 306 | 'title' => esc_html__( 'Login settings', 'wp-react-plugin-boilerplate' ), 307 | ), 308 | array( 309 | 'icon' => '', 310 | 'title' => esc_html__( 'Dashboard settings', 'wp-react-plugin-boilerplate' ), 311 | ), 312 | ), 313 | 'normalColumns' => array( 314 | array( 315 | 'icon' => '', 316 | 'title' => esc_html__( 'Knowledge base', 'wp-react-plugin-boilerplate' ), 317 | 'content' => esc_html__( 318 | 'The utilization of this plugin can be facilitated by perusing comprehensive and well-documented articles.', 319 | 'wp-react-plugin-boilerplate' 320 | ), 321 | 'buttonText' => esc_html__( 'Visit knowledge base', 'wp-react-plugin-boilerplate' ), 322 | 'buttonLink' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 323 | 324 | ), 325 | array( 326 | 'icon' => '', 327 | 'title' => esc_html__( 'Community', 'wp-react-plugin-boilerplate' ), 328 | 'content' => sprintf( 329 | /* translators: %s is the plugin name */ 330 | esc_html__( 331 | 'Our objective is to enhance the customer experience, we invite you to join our community where you can receive immediate support.', 332 | 'wp-react-plugin-boilerplate' 333 | ), 334 | $plugin_name, 335 | ), 336 | 'buttonText' => esc_html__( 'Visit community page', 'wp-react-plugin-boilerplate' ), 337 | 'buttonLink' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 338 | ), 339 | array( 340 | 'icon' => '', 341 | 'title' => esc_html__( '24x7 support', 'wp-react-plugin-boilerplate' ), 342 | 'content' => sprintf( 343 | /* translators: %s is the plugin name */ 344 | esc_html__( 345 | 'Our support team is available 24/7 to assist you in the event that you encounter any problems while utilizing this plugin.', 346 | 'wp-react-plugin-boilerplate' 347 | ), 348 | $plugin_name, 349 | ), 350 | 'buttonText' => esc_html__( 'Create a support thread', 'wp-react-plugin-boilerplate' ), 351 | 'buttonLink' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 352 | 353 | ), 354 | array( 355 | 'icon' => '', 356 | 'title' => esc_html__( 'Video guide', 'wp-react-plugin-boilerplate' ), 357 | 'content' => sprintf( 358 | /* translators: %s is the plugin name */ 359 | esc_html__( 360 | 'The plugin is accompanied by comprehensive video tutorials that provide practical demonstrations for most customization.', 361 | 'wp-react-plugin-boilerplate' 362 | ), 363 | $plugin_name, 364 | ), 365 | 'buttonText' => esc_html__( 'View video guide', 'wp-react-plugin-boilerplate' ), 366 | 'buttonLink' => 'https://github.com/codersantosh/wp-react-plugin-boilerplate', 367 | 368 | ), 369 | ), 370 | 'topicLinks' => array( 371 | 'icon' => '', 372 | 'title' => esc_html__( 'Quick links to settings', 'wp-react-plugin-boilerplate' ), 373 | 'columns' => array( 374 | array( 375 | 'icon' => '', 376 | 'title' => esc_html__( 'Settings 1', 'wp-react-plugin-boilerplate' ), 377 | 'link' => '#/settings/setting1', 378 | 'variant' => 'light', 379 | 'target' => '_self', 380 | ), 381 | array( 382 | 'icon' => '', 383 | 'title' => esc_html__( 'Settings 1', 'wp-react-plugin-boilerplate' ), 384 | 'link' => '#/settings/setting2', 385 | 'variant' => 'light', 386 | 'target' => '_self', 387 | 388 | ), 389 | array( 390 | 'icon' => '', 391 | 'title' => esc_html__( 'Advanced settings', 'wp-react-plugin-boilerplate' ), 392 | 'link' => '#/settings/advanced', 393 | 'variant' => 'light', 394 | 'target' => '_self', 395 | 396 | ), 397 | ), 398 | ), 399 | 'changelog' => array( 400 | 'icon' => '', 401 | 'title' => esc_html__( 'Changelog', 'wp-react-plugin-boilerplate' ), 402 | 'content' => wp_react_plugin_boilerplate_parse_changelog(), 403 | ), 404 | ), 405 | ) 406 | ); 407 | if ( ! empty( $key ) ) { 408 | return $options[ $key ]; 409 | } else { 410 | return $options; 411 | } 412 | } 413 | endif; 414 | -------------------------------------------------------------------------------- /includes/index.php: -------------------------------------------------------------------------------- 1 | 33 | */ 34 | class Wp_React_Plugin_Boilerplate { 35 | 36 | /** 37 | * The loader that's responsible for maintaining and registering all hooks that power 38 | * the plugin. 39 | * 40 | * @since 1.0.0 41 | * @access protected 42 | * @var Wp_React_Plugin_Boilerplate_Loader $loader Maintains and registers all hooks for the plugin. 43 | */ 44 | protected $loader; 45 | 46 | /** 47 | * Define the core functionality of the plugin. 48 | * 49 | * Set the plugin name and the plugin version that can be used throughout the plugin. 50 | * Load the dependencies, define the locale, and set the hooks for the admin area and 51 | * the public-facing side of the site. 52 | * 53 | * @since 1.0.0 54 | */ 55 | public function __construct() { 56 | 57 | $this->load_dependencies(); 58 | $this->set_locale(); 59 | $this->define_include_hooks(); 60 | $this->define_admin_hooks(); 61 | $this->define_public_hooks(); 62 | } 63 | 64 | /** 65 | * Load the required dependencies for this plugin. 66 | * 67 | * Include the following files that make up the plugin: 68 | * 69 | * - Wp_React_Plugin_Boilerplate_Loader. Orchestrates the hooks of the plugin. 70 | * - Wp_React_Plugin_Boilerplate_i18n. Defines internationalization functionality. 71 | * - Wp_React_Plugin_Boilerplate_Admin. Defines all hooks for the admin area. 72 | * - Wp_React_Plugin_Boilerplate_Public. Defines all hooks for the public side of the site. 73 | * 74 | * Create an instance of the loader which will be used to register the hooks 75 | * with WordPress. 76 | * 77 | * @since 1.0.0 78 | * @access private 79 | */ 80 | private function load_dependencies() { 81 | 82 | /* API */ 83 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'includes/api/index.php'; 84 | 85 | /**Plugin Core Functions*/ 86 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'includes/functions.php'; 87 | 88 | /** 89 | * The class responsible for orchestrating the actions and filters of the 90 | * core plugin. 91 | */ 92 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'includes/class-loader.php'; 93 | 94 | /** 95 | * The class responsible for defining internationalization functionality 96 | * of the plugin. 97 | */ 98 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'includes/class-i18n.php'; 99 | 100 | /** 101 | * The class responsible for defining all actions that occur in both admin and public area. 102 | */ 103 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'includes/class-include.php'; 104 | 105 | /** 106 | * The class responsible for defining all actions that occur in the admin area. 107 | */ 108 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'admin/class-admin.php'; 109 | 110 | /** 111 | * The class responsible for defining all actions that occur in the public-facing 112 | * side of the site. 113 | */ 114 | require_once WP_REACT_PLUGIN_BOILERPLATE_PATH . 'public/class-public.php'; 115 | 116 | $this->loader = new Wp_React_Plugin_Boilerplate_Loader(); 117 | } 118 | 119 | /** 120 | * Define the locale for this plugin for internationalization. 121 | * 122 | * Uses the Wp_React_Plugin_Boilerplate_i18n class in order to set the domain and to register the hook 123 | * with WordPress. 124 | * 125 | * @since 1.0.0 126 | * @access private 127 | */ 128 | private function set_locale() { 129 | 130 | $plugin_i18n = new Wp_React_Plugin_Boilerplate_i18n(); 131 | 132 | $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' ); 133 | } 134 | 135 | /** 136 | * Register all of the hooks related to both admin and public-facing areas functionality 137 | * of the plugin. 138 | * 139 | * @since 1.0.0 140 | * @access private 141 | */ 142 | private function define_include_hooks() { 143 | 144 | $plugin_include = wp_react_plugin_boilerplate_include(); 145 | 146 | /* Register scripts and styles */ 147 | $this->loader->add_action( 'init', $plugin_include, 'register_scripts_and_styles' ); 148 | } 149 | 150 | /** 151 | * Register all of the hooks related to the admin area functionality 152 | * of the plugin. 153 | * 154 | * @since 1.0.0 155 | * @access private 156 | */ 157 | private function define_admin_hooks() { 158 | 159 | $plugin_admin = wp_react_plugin_boilerplate_admin(); 160 | 161 | $this->loader->add_action( 'admin_menu', $plugin_admin, 'add_admin_menu' ); 162 | $this->loader->add_filter( 'admin_body_class', $plugin_admin, 'add_has_sticky_header' ); 163 | $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_resources' ); 164 | 165 | /*Register Settings*/ 166 | $this->loader->add_action( 'rest_api_init', $plugin_admin, 'register_settings' ); 167 | $this->loader->add_action( 'admin_init', $plugin_admin, 'register_settings' ); 168 | 169 | $this->loader->add_filter( 'plugin_action_links_wp-react-plugin-boilerplate/wp-react-plugin-boilerplate.php', $plugin_admin, 'add_plugin_links', 10, 4 ); 170 | } 171 | 172 | /** 173 | * Register all of the hooks related to the public-facing functionality 174 | * of the plugin. 175 | * 176 | * @since 1.0.0 177 | * @access private 178 | */ 179 | private function define_public_hooks() { 180 | 181 | $plugin_public = wp_react_plugin_boilerplate_public(); 182 | 183 | $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_public_resources' ); 184 | } 185 | 186 | /** 187 | * Run the loader to execute all of the hooks with WordPress. 188 | * 189 | * @since 1.0.0 190 | */ 191 | public function run() { 192 | $this->loader->run(); 193 | } 194 | 195 | /** 196 | * The reference to the class that orchestrates the hooks with the plugin. 197 | * 198 | * @since 1.0.0 199 | * @return Wp_React_Plugin_Boilerplate_Loader Orchestrates the hooks of the plugin. 200 | */ 201 | public function get_loader() { 202 | return $this->loader; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | \n" 8 | "Language-Team: LANGUAGE \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2024-10-30T09:48:07+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.6.0\n" 15 | "X-Domain: wp-react-plugin-boilerplate\n" 16 | 17 | #: src/admin/components/atoms/save-settings.js:24 18 | msgid "Saved" 19 | msgstr "" 20 | 21 | #: src/admin/components/atoms/save-settings.js:25 22 | msgid "Save settings" 23 | msgstr "" 24 | 25 | #: src/admin/components/atoms/save-settings.js:26 26 | msgid "Saving" 27 | msgstr "" 28 | 29 | #: src/admin/components/molecules/docs-title.js:15 30 | msgid "Documentation" 31 | msgstr "" 32 | 33 | #: src/admin/components/organisms/admin-header.js:24 34 | msgid "Getting started" 35 | msgstr "" 36 | 37 | #: src/admin/components/organisms/admin-header.js:29 38 | #: src/admin/pages/settings/pages/settings1.js:133 39 | #: src/admin/pages/settings/pages/settings2.js:154 40 | #: admin/class-admin.php:273 41 | #: deploy/admin/class-admin.php:273 42 | msgid "Settings" 43 | msgstr "" 44 | 45 | #: src/admin/components/organisms/admin-header.js:47 46 | msgid "Show all hidden informations, notices and documentations " 47 | msgstr "" 48 | 49 | #: src/admin/pages/settings/pages/advanced.js:121 50 | #: src/admin/pages/settings/routes.js:85 51 | msgid "Advanced" 52 | msgstr "" 53 | 54 | #: src/admin/pages/settings/pages/advanced.js:38 55 | msgid "Remove all plugin settings when deactivating." 56 | msgstr "" 57 | 58 | #: src/admin/pages/settings/pages/advanced.js:73 59 | msgid "What does \"Remove all plugin settings when deactivating\" do?" 60 | msgstr "" 61 | 62 | #: src/admin/pages/settings/pages/advanced.js:81 63 | msgid "Enabling this option will erase all settings associated with the plugin from the WordPress options table. However, please note that the selected page will not be deleted from Pages." 64 | msgstr "" 65 | 66 | #: src/admin/pages/settings/pages/advanced.js:88 67 | msgid "Do I need to activate this option?" 68 | msgstr "" 69 | 70 | #: src/admin/pages/settings/pages/advanced.js:93 71 | msgid "If you anticipate using the `Login feature` in the future, no need to activate it." 72 | msgstr "" 73 | 74 | #: src/admin/pages/settings/pages/settings1.js:100 75 | msgid "FAQ Query 2?" 76 | msgstr "" 77 | 78 | #: src/admin/pages/settings/pages/settings1.js:105 79 | msgid "FAQ Answer 2" 80 | msgstr "" 81 | 82 | #: src/admin/pages/settings/pages/settings1.js:38 83 | msgid "Setting 1" 84 | msgstr "" 85 | 86 | #: src/admin/pages/settings/pages/settings1.js:39 87 | msgid "Enter Text" 88 | msgstr "" 89 | 90 | #: src/admin/pages/settings/pages/settings1.js:49 91 | msgid "Setting 2" 92 | msgstr "" 93 | 94 | #: src/admin/pages/settings/pages/settings1.js:50 95 | msgid "Enter Another Text" 96 | msgstr "" 97 | 98 | #: src/admin/pages/settings/pages/settings1.js:85 99 | msgid "FAQ Query 1?" 100 | msgstr "" 101 | 102 | #: src/admin/pages/settings/pages/settings1.js:93 103 | msgid "FAQ Answer 1" 104 | msgstr "" 105 | 106 | #: src/admin/pages/settings/pages/settings2.js:106 107 | msgid "FAQ Query 3?" 108 | msgstr "" 109 | 110 | #: src/admin/pages/settings/pages/settings2.js:114 111 | msgid "FAQ Answer 3" 112 | msgstr "" 113 | 114 | #: src/admin/pages/settings/pages/settings2.js:121 115 | msgid "FAQ Query 4?" 116 | msgstr "" 117 | 118 | #: src/admin/pages/settings/pages/settings2.js:126 119 | msgid "FAQ Answer 4" 120 | msgstr "" 121 | 122 | #: src/admin/pages/settings/pages/settings2.js:50 123 | msgid "Check to enable" 124 | msgstr "" 125 | 126 | #: src/admin/pages/settings/pages/settings2.js:61 127 | msgid "Setting 5 Select" 128 | msgstr "" 129 | 130 | #: src/admin/pages/settings/pages/settings2.js:65 131 | msgid "Option 1" 132 | msgstr "" 133 | 134 | #: src/admin/pages/settings/pages/settings2.js:69 135 | msgid "Option 2" 136 | msgstr "" 137 | 138 | #: src/admin/pages/settings/routes.js:77 139 | #: deploy/includes/functions.php:376 140 | #: deploy/includes/functions.php:383 141 | #: includes/functions.php:376 142 | #: includes/functions.php:383 143 | msgid "Settings 1" 144 | msgstr "" 145 | 146 | #: src/admin/pages/settings/routes.js:81 147 | msgid "Settings 2" 148 | msgstr "" 149 | 150 | #. Plugin Name of the plugin 151 | msgid "WP React Plugin Boilerplate - WordPress Setting via React and Rest API" 152 | msgstr "" 153 | 154 | #. Plugin URI of the plugin 155 | msgid "https://www.addonspress.com/wordpress-starter-plugins/wp-react-plugin-boilerplate" 156 | msgstr "" 157 | 158 | #. Description of the plugin 159 | msgid "WordPress Setting via React and Rest API." 160 | msgstr "" 161 | 162 | #. Author of the plugin 163 | msgid "codersantosh" 164 | msgstr "" 165 | 166 | #. Author URI of the plugin 167 | msgid "https://www.acmeit.org/" 168 | msgstr "" 169 | 170 | #. translators: %s: Property name. 171 | #: deploy/includes/api/class-api-settings.php:144 172 | #: includes/api/class-api-settings.php:144 173 | msgid "The %s property has an invalid stored value, and cannot be updated to null." 174 | msgstr "" 175 | 176 | #: deploy/includes/api/class-api.php:115 177 | #: deploy/includes/api/class-api.php:127 178 | #: includes/api/class-api.php:115 179 | #: includes/api/class-api.php:127 180 | msgid "Cheatin’ huh?" 181 | msgstr "" 182 | 183 | #: deploy/includes/functions.php:28 184 | #: includes/functions.php:28 185 | msgid "Default Setting 1" 186 | msgstr "" 187 | 188 | #: deploy/includes/functions.php:29 189 | #: includes/functions.php:29 190 | msgid "Default Setting 2" 191 | msgstr "" 192 | 193 | #: deploy/includes/functions.php:175 194 | #: includes/functions.php:175 195 | msgid "WP React Plugin Boilerplate" 196 | msgstr "" 197 | 198 | #: deploy/includes/functions.php:182 199 | #: includes/functions.php:182 200 | msgid "ReactJs Settings Page" 201 | msgstr "" 202 | 203 | #: deploy/includes/functions.php:183 204 | #: includes/functions.php:183 205 | msgid "ReactJs Settings" 206 | msgstr "" 207 | 208 | #. translators: %s is the plugin name 209 | #: deploy/includes/functions.php:192 210 | #: includes/functions.php:192 211 | msgid "Congratulations on choosing the %s for creating your plugin. We recommend taking a few minutes to read the following information on how the plugin works. Please read it carefully to fully understand the capabilities of the plugin and how to use them effectively." 212 | msgstr "" 213 | 214 | #. translators: %s is the plugin name 215 | #: deploy/includes/functions.php:204 216 | #: includes/functions.php:204 217 | msgid "Congratulations! You have successfully installed %s and it is ready for customization. Feel free to add/edit any files." 218 | msgstr "" 219 | 220 | #. translators: %s is the plugin name 221 | #: deploy/includes/functions.php:212 222 | #: includes/functions.php:212 223 | msgid "If you have any questions or need assistance, please do not hesitate to contact us for support. The %s plugin caters to WordPress developers and designers seeking to quickly start developing WordPress plugins in a modern way using ReactJS, Rest API." 224 | msgstr "" 225 | 226 | #: deploy/includes/functions.php:221 227 | #: includes/functions.php:221 228 | msgid "Get started" 229 | msgstr "" 230 | 231 | #: deploy/includes/functions.php:227 232 | #: includes/functions.php:227 233 | msgid "Docmentation" 234 | msgstr "" 235 | 236 | #: deploy/includes/functions.php:233 237 | #: includes/functions.php:233 238 | msgid "Get support" 239 | msgstr "" 240 | 241 | #: deploy/includes/functions.php:247 242 | #: includes/functions.php:247 243 | msgid "Visit site" 244 | msgstr "" 245 | 246 | #: deploy/includes/functions.php:252 247 | #: deploy/includes/functions.php:264 248 | #: includes/functions.php:252 249 | #: includes/functions.php:264 250 | msgid "Get Support" 251 | msgstr "" 252 | 253 | #: deploy/includes/functions.php:259 254 | #: includes/functions.php:259 255 | msgid "Contact Information" 256 | msgstr "" 257 | 258 | #: deploy/includes/functions.php:263 259 | #: includes/functions.php:263 260 | msgid "Support" 261 | msgstr "" 262 | 263 | #: deploy/includes/functions.php:270 264 | #: includes/functions.php:270 265 | msgid "Email" 266 | msgstr "" 267 | 268 | #: deploy/includes/functions.php:271 269 | #: includes/functions.php:271 270 | msgid "codersantosh@gmail.com" 271 | msgstr "" 272 | 273 | #: deploy/includes/functions.php:277 274 | #: includes/functions.php:277 275 | msgid "Location" 276 | msgstr "" 277 | 278 | #: deploy/includes/functions.php:278 279 | #: includes/functions.php:278 280 | msgid "Kathmandu, Nepal" 281 | msgstr "" 282 | 283 | #: deploy/includes/functions.php:302 284 | #: includes/functions.php:302 285 | msgid "Activate Plugin" 286 | msgstr "" 287 | 288 | #: deploy/includes/functions.php:306 289 | #: includes/functions.php:306 290 | msgid "Login settings" 291 | msgstr "" 292 | 293 | #: deploy/includes/functions.php:310 294 | #: includes/functions.php:310 295 | msgid "Dashboard settings" 296 | msgstr "" 297 | 298 | #: deploy/includes/functions.php:316 299 | #: includes/functions.php:316 300 | msgid "Knowledge base" 301 | msgstr "" 302 | 303 | #: deploy/includes/functions.php:317 304 | #: includes/functions.php:317 305 | msgid "The utilization of this plugin can be facilitated by perusing comprehensive and well-documented articles." 306 | msgstr "" 307 | 308 | #: deploy/includes/functions.php:321 309 | #: includes/functions.php:321 310 | msgid "Visit knowledge base" 311 | msgstr "" 312 | 313 | #: deploy/includes/functions.php:327 314 | #: includes/functions.php:327 315 | msgid "Community" 316 | msgstr "" 317 | 318 | #. translators: %s is the plugin name 319 | #: deploy/includes/functions.php:330 320 | #: includes/functions.php:330 321 | msgid "Our objective is to enhance the customer experience, we invite you to join our community where you can receive immediate support." 322 | msgstr "" 323 | 324 | #: deploy/includes/functions.php:336 325 | #: includes/functions.php:336 326 | msgid "Visit community page" 327 | msgstr "" 328 | 329 | #: deploy/includes/functions.php:341 330 | #: includes/functions.php:341 331 | msgid "24x7 support" 332 | msgstr "" 333 | 334 | #. translators: %s is the plugin name 335 | #: deploy/includes/functions.php:344 336 | #: includes/functions.php:344 337 | msgid "Our support team is available 24/7 to assist you in the event that you encounter any problems while utilizing this plugin." 338 | msgstr "" 339 | 340 | #: deploy/includes/functions.php:350 341 | #: includes/functions.php:350 342 | msgid "Create a support thread" 343 | msgstr "" 344 | 345 | #: deploy/includes/functions.php:356 346 | #: includes/functions.php:356 347 | msgid "Video guide" 348 | msgstr "" 349 | 350 | #. translators: %s is the plugin name 351 | #: deploy/includes/functions.php:359 352 | #: includes/functions.php:359 353 | msgid "The plugin is accompanied by comprehensive video tutorials that provide practical demonstrations for most customization." 354 | msgstr "" 355 | 356 | #: deploy/includes/functions.php:365 357 | #: includes/functions.php:365 358 | msgid "View video guide" 359 | msgstr "" 360 | 361 | #: deploy/includes/functions.php:372 362 | #: includes/functions.php:372 363 | msgid "Quick links to settings" 364 | msgstr "" 365 | 366 | #: deploy/includes/functions.php:391 367 | #: includes/functions.php:391 368 | msgid "Advanced settings" 369 | msgstr "" 370 | 371 | #: deploy/includes/functions.php:401 372 | #: includes/functions.php:401 373 | msgid "Changelog" 374 | msgstr "" 375 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp-react-plugin-boilerplate", 3 | "version": "1.0.0", 4 | "description": "WP React Plugin Boilerplate - WordPress Setting via React and Rest API", 5 | "author": "codersantosh", 6 | "license": "GPL-2.0-or-later", 7 | "main": "build/index.js", 8 | "scripts": { 9 | "build:admin": "wp-scripts build --webpack-src-dir=src/admin --output-path=build/admin", 10 | "build:public": "wp-scripts build --webpack-src-dir=src/public --output-path=build/public", 11 | "build": "npm-run-all build:admin build:public", 12 | "start:admin": "wp-scripts start --webpack-src-dir=src/admin --output-path=build/admin", 13 | "start:public": "wp-scripts start --webpack-src-dir=src/public --output-path=build/public", 14 | "start": "npm-run-all --parallel start:admin start:public", 15 | "packages-update": "wp-scripts packages-update", 16 | "makejsstring": "node .bin/make-string.js", 17 | "makepot": "wp i18n make-pot . languages/wp-react-plugin-boilerplate.pot --skip-js --exclude=src,vendor,node_modules --merge=languages/js.pot", 18 | "copy": "node .bin/copy.js", 19 | "replaceAtrc": "node .bin/replace-atrc.js", 20 | "deploy": "npm-run-all build replaceAtrc makepot copy", 21 | "initial-rename": "node .bin/initial-rename.js" 22 | }, 23 | "devDependencies": { 24 | "@wordpress/babel-plugin-makepot": "^6.19.0", 25 | "@wordpress/scripts": "^30.12.0", 26 | "autoprefixer": "^10.4.7", 27 | "ncp": "^2.0.0", 28 | "npm-run-all": "^4.1.5", 29 | "replace-in-file": "^7.2.0" 30 | }, 31 | "dependencies": { 32 | "@wordpress/components": "^29.5.0", 33 | "@wordpress/url": "^4.19.0", 34 | "atrc": "^1.0.35", 35 | "classnames": "^2.5.1", 36 | "lodash": "^4.17.21", 37 | "react-router-dom": "^6.3.0" 38 | }, 39 | "browserslist": [ 40 | "last 3 versions", 41 | "> 1%" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /process.md: -------------------------------------------------------------------------------- 1 | # WP React Plugin Boilerplate 2 | 3 | WP React Plugin Boilerplate is a starter WordPress plugin to develop WordPress Plugin via React and Rest API. 4 | 5 | ## Self Introduction 6 | ![Santosh Kunwar](https://avatars.githubusercontent.com/u/7057447?s=48&v=4?raw=true) 7 | 8 | Santosh Kunwar, Founder/CEO at [Acme Themes](https://www.acmethemes.com/ ), [Acme Information Technology](https://www.acmeit.org/ ), and a popular Gutenberg Page Builder - [Gutentor]( https://wordpress.org/plugins/gutentor/ ) creator, who loves working on WordPress Themes, Plugins and recently on [Gutenberg Templates]( https://templateberg.com/gutenberg-templates/ ). A dynamic person who evolving with WordPress and has more than a decade of experience working with WordPress. 9 | WordPress Profile of [codersantosh](https://profiles.wordpress.org/codersantosh/) 10 | In short, I just love WordPress more… 11 | 12 | ## Output of Project 13 | ![WP React Plugin Boilerplate output](https://raw.githubusercontent.com/codersantosh/wp-react-plugin-boilerplate/master/assets/img/output.jpg) 14 | 15 | ## Basic Introduction to WordPress plugin 16 | 17 | A WordPress plugin is a piece of software that extends or enhances the functionality of a WordPress website. It is a set of PHP, HTML, CSS, and possibly JavaScript files that can be easily added to a WordPress site to introduce new features or modify existing ones. WordPress plugins are designed to be modular and customizable, allowing users to tailor the functionality of their websites without directly modifying the core WordPress code. 18 | 19 | [Reference: Plugin Handbook](https://developer.wordpress.org/plugins/) 20 | 21 | ## Basic Introduction to ReactJS 22 | 23 | - ReactJS is a component-based front-end JavaScript library. 24 | - It is open-source. 25 | - Components: A small and isolated piece of code. Build Complex UIs combining “components”. Components are reusable. 26 | - JSX (JavaScript XML): Markup syntax, similar to HTML. 27 | - React component “STATE”: An object that determines how that component renders & and behaves. Use “state” to create dynamic and interactive components. 28 | - Created by Jordan Walke, who was a software engineer at Facebook. Introduced in 2011 on Facebook's News Feed, and open-sourced in 2013. 29 | 30 | [Reference: ReactJS]( https://reactjs.org/) 31 | 32 | ## Basic Introduction to WordPress Rest API 33 | 34 | - An interface or communication protocol for sending and receiving data as JSON (JavaScript Object Notation) objects between the client site and server site. 35 | - Released on the core in version 4.7 in December 2016. 36 | - Provide an application platform for WordPress. 37 | - Rest Route: URI which can be mapped to different HTTP methods for Request and Get Response. 38 | 39 | [Reference: REST API Handbook]( https://developer.wordpress.org/rest-api/) 40 | 41 | ## Development Process 42 | 43 | ### Install Activate and Basic Introduction of the Plugin 44 | ```sh 45 | git checkout 1basicplugin 46 | ``` 47 | 48 | ### Setting Plugin Default Options, Getting Options, Deleting Options, and Setting Options 49 | ```sh 50 | git checkout 2optionsfunctions 51 | ``` 52 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/includes/functions.php 53 | 54 | ### Adding WordPress Admin Menu for Our Plugin 55 | ```sh 56 | git checkout 3adminmenu 57 | ``` 58 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/includes/class-wp-react-plugin-boilerplate.php#L169 59 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L60 60 | 61 | #### Reference: 62 | - https://developer.wordpress.org/reference/hooks/admin_menu/ 63 | - https://developer.wordpress.org/reference/functions/add_menu_page/ 64 | 65 | 66 | ### Adding ReactJS to our Plugin 67 | Should have Installed Node.js + npm (https://nodejs.org/en/download/) 68 | ```sh 69 | git checkout 4initreact 70 | npm install 71 | npm run start 72 | ``` 73 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L99 74 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L109 75 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/tree/master/src 76 | 77 | 78 | #### Reference: 79 | - https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/ 80 | - https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/ 81 | - https://developer.wordpress.org/block-editor/reference-guides/packages/packages-element/ 82 | 83 | ### Implementing ReactJS on the WordPress Admin Menu 84 | ```sh 85 | git checkout 5ReactOnWpMenu 86 | ``` 87 | #### Reference: 88 | - https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/ 89 | - https://developer.wordpress.org/reference/functions/get_current_screen/ 90 | - https://developer.wordpress.org/reference/functions/wp_enqueue_script/ 91 | - https://developer.wordpress.org/reference/functions/wp_enqueue_style/ 92 | - https://developer.wordpress.org/reference/functions/wp_set_script_translations/ 93 | - https://developer.wordpress.org/reference/functions/wp_localize_script/ 94 | 95 | ### Adding Default Gutenberg Components 96 | ```sh 97 | git checkout 6GutenbergComponents 98 | ``` 99 | #### Reference: 100 | - https://developer.wordpress.org/block-editor/reference-guides/components/ 101 | 102 | ### State and Lifecycle to Components 103 | ```sh 104 | git checkout 7StateLifecycle 105 | ``` 106 | #### Reference: 107 | - https://reactjs.org/docs/state-and-lifecycle.html 108 | - https://reactjs.org/docs/hooks-state.html 109 | 110 | 111 | ### Custom Components 112 | ```sh 113 | git checkout 8CustomComponents 114 | ``` 115 | #### Reference: 116 | - https://developer.wordpress.org/block-editor/reference-guides/components/tab-panel/ 117 | 118 | ### Using Rest API to get Plugin Options and Setting it on React Component Setting Fields 119 | ```sh 120 | git checkout 9RestApiGetOptions 121 | ``` 122 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L151 123 | 124 | 125 | #### Reference: 126 | - https://developer.wordpress.org/reference/hooks/rest_api_init/ 127 | - https://developer.wordpress.org/reference/functions/register_rest_route/ 128 | - https://developer.wordpress.org/block-editor/reference-guides/packages/packages-api-fetch/ 129 | 130 | ### Using Rest API to set Plugin Options and Setting it on the Database ( WordPress Option Table ) 131 | ```sh 132 | git checkout 10RestApiSetOptions 133 | ``` 134 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L154 135 | - https://github.com/codersantosh/wp-react-plugin-boilerplate/blob/master/admin/class-wp-react-plugin-boilerplate-admin.php#L192 136 | 137 | ### Real-Time Use of Option 138 | ```sh 139 | git checkout 10RestApiSetOptions 140 | ``` 141 | - https://github.com/codersantosh/wp-react-plugin-boilerplate 142 | 143 | ### Finalization 144 | ```sh 145 | git checkout master 146 | ``` 147 | - https://github.com/codersantosh/wp-react-plugin-boilerplate 148 | 149 | ### Queries? 150 | Any queries? 151 | 152 | ### Exercise to create new fields 153 | 154 | - Create Each New Field on Each General and Advanced Tab 155 | - Rename Existing Tab 156 | - Add New Tab with New Settings 157 | 158 | ### Thanks 159 | -------------------------------------------------------------------------------- /public/class-public.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Wp_React_Plugin_Boilerplate_Public { 27 | 28 | /** 29 | * Gets an instance of this object. 30 | * Prevents duplicate instances which avoid artefacts and improves performance. 31 | * 32 | * @static 33 | * @access public 34 | * @return object 35 | * @since 1.0.0 36 | */ 37 | public static function get_instance() { 38 | // Store the instance locally to avoid private static replication. 39 | static $instance = null; 40 | 41 | // Only run these methods if they haven't been ran previously. 42 | if ( null === $instance ) { 43 | $instance = new self(); 44 | } 45 | 46 | // Always return the instance. 47 | return $instance; 48 | } 49 | 50 | /** 51 | * Register the JavaScript and stylesheets for the public-facing side of the site. 52 | * 53 | * @since 1.0.0 54 | */ 55 | public function enqueue_public_resources() { 56 | /** 57 | * This function is provided for demonstration purposes only. 58 | * 59 | * An instance of this class should be passed to the run() function 60 | * defined in Wp_React_Plugin_Boilerplate_Loader as all of the hooks are defined 61 | * in that particular class. 62 | * 63 | * The Wp_React_Plugin_Boilerplate_Loader will then create the relationship 64 | * between the defined hooks and the functions defined in this 65 | * class. 66 | */ 67 | /* Atomic CSS */ 68 | wp_enqueue_style( 'atomic' ); 69 | wp_style_add_data( 'atomic', 'rtl', 'replace' ); 70 | 71 | $version = WP_REACT_PLUGIN_BOILERPLATE_VERSION; 72 | 73 | wp_enqueue_style( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_URL . 'build/public/index.css', array(), $version ); 74 | wp_style_add_data( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 'rtl', 'replace' ); 75 | 76 | /*Scripts dependency files*/ 77 | $deps_file = WP_REACT_PLUGIN_BOILERPLATE_PATH . 'build/public/index.asset.php'; 78 | 79 | /*Fallback dependency array*/ 80 | $dependency = array(); 81 | 82 | /*Set dependency and version*/ 83 | if ( file_exists( $deps_file ) ) { 84 | $deps_file = require $deps_file; 85 | $dependency = $deps_file['dependencies']; 86 | $version = $deps_file['version']; 87 | } 88 | 89 | wp_enqueue_script( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_URL . 'build/public/index.js', $dependency, $version, true ); 90 | wp_set_script_translations( WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME ); 91 | 92 | $localize = apply_filters( 93 | 'wp_react_plugin_boilerplate_public_localize', 94 | array( 95 | 'WP_REACT_PLUGIN_BOILERPLATE_URL' => WP_REACT_PLUGIN_BOILERPLATE_URL, 96 | 'site_url' => esc_url( home_url() ), 97 | 'rest_url' => get_rest_url(), 98 | 'nonce' => wp_create_nonce( 'wp_rest' ), 99 | ) 100 | ); 101 | 102 | wp_add_inline_script( 103 | WP_REACT_PLUGIN_BOILERPLATE_PLUGIN_NAME, 104 | sprintf( 105 | "var WpReactPluginBoilerplateLocalize = JSON.parse( decodeURIComponent( '%s' ) );", 106 | rawurlencode( 107 | wp_json_encode( 108 | $localize 109 | ) 110 | ), 111 | ), 112 | 'before' 113 | ); 114 | } 115 | } 116 | 117 | if ( ! function_exists( 'wp_react_plugin_boilerplate_public' ) ) { 118 | /** 119 | * Return instance of Wp_React_Plugin_Boilerplate_Public class 120 | * 121 | * @since 1.0.0 122 | * 123 | * @return Wp_React_Plugin_Boilerplate_Public 124 | */ 125 | function wp_react_plugin_boilerplate_public() {//phpcs:ignore 126 | return Wp_React_Plugin_Boilerplate_Public::get_instance(); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | `WP React Plugin Boilerplate` is a starter WordPress plugin to develop WordPress Plugin via React and Rest API. The Plugin Settings was added by React, Gutenberg Components and Rest API 6 | 7 | ## Description 8 | 9 | This boilerplate provides a foundation for building modern WordPress plugins. 10 | 11 | ## Table of Contents 12 | 13 | - [WP React Plugin Boilerplate](#wp-react-plugin-boilerplate) 14 | - [Description](#description) 15 | - [Table of Contents](#table-of-contents) 16 | - [Features](#features) 17 | - [Getting Started](#getting-started) 18 | - [1. Installation](#1-installation) 19 | - [2. Development Setup](#2-development-setup) 20 | - [3. Renaming the Plugin](#3-renaming-the-plugin) 21 | - [4. Activate the Plugin](#4-activate-the-plugin) 22 | - [5. Start Customization and Coding](#5-start-customization-and-coding) 23 | - [Folder Information](#folder-information) 24 | - [Changelog](#changelog) 25 | - [Contributing](#contributing) 26 | - [Authors](#authors) 27 | - [Recommendations](#recommendations) 28 | - [License & Attribution](#license--attribution) 29 | 30 | ## Features 31 | 32 | - **Easy Renaming:** Simplify renaming of plugin files, constants, variables, classes, text-domain, and functions. 33 | 34 | - Edit the `initial-rename.js` file in the .bin directory. 35 | - Adjust the naming strings. 36 | - Run `npm run initial-rename` 37 | 38 | - **Development Environment Setup:** 39 | 40 | - Includes `npm run start` command to initialize React JS development environment with a live development server. 41 | 42 | - **Production Build:** 43 | 44 | - Provides `npm run build` command to generate optimized production files for the plugin. 45 | 46 | - **Language File Creation:** 47 | 48 | - Generates `.pot` files from both JavaScript and PHP code. 49 | - Includes the `npm run makepot` command to generate the `.pot` file. Note: The JavaScript language file is created using `@wordpress/babel-preset-default`. The `npm run makepot` command utilizes WP-CLI to generate PHP file translations and merge them with the `JavaScript .pot` file to produce the final `.pot` file. 50 | 51 | - **Deployment Command:** 52 | 53 | - Run `npm run deploy` to create a production-ready deploy folder. 54 | - Rename and upload this folder to your WordPress site or WordPress.org after thorough testing. 55 | 56 | - **REST API Integration:** 57 | 58 | - Utilizes WordPress REST API for backend interactions, found in includes/api directory. 59 | 60 | - **[Utilizes Atrc (atrc) - Atomic React Components](https://github.com/codersantosh/atrc):** 61 | 62 | - ATRC, or Atomic React Components, is integrated into the WP React Plugin Boilerplate to provide a structured approach to building React components. 63 | - ATRC uses most of the features from core Gutenberg, enhancing compatibility and leveraging established Gutenberg functionality. 64 | - It promotes component reusability and maintainability by breaking down UI elements into smaller, atomic components such as molecules, controls, and templates. 65 | - It facilitates easy handling of WordPress API and data related to settings, posts, or any other data and API. 66 | 67 | - **[Utilizes Atomic CSS](https://github.com/codersantosh/atomic-css):** 68 | 69 | - Atomic CSS is incorporated into the WP React Plugin Boilerplate to streamline the styling process. 70 | 71 | - **[Atomic React Components](https://github.com/codersantosh/atrc) `atrc-prefix-atrc` text domain replacement command:** 72 | 73 | - Provides `npm run replaceAtrc` command to replace `atrc-prefix-atrc` text domain with your plugin's text domain. 74 | 75 | - **Customization Encouraged:** 76 | 77 | - Since the WP React Plugin Boilerplate is designed to be highly customizable, developers are encouraged to modify and adapt both ATRC and Atomic CSS according to their specific project requirements. 78 | - Developers are encouraged to customize any aspect of the plugin's structure, styling, or functionality according to their needs. They can remove existing libraries and/or integrate additional React, CSS, or JavaScript libraries, including Gutenberg libraries, and modify them based on their preferences and expertise. It's important to view this plugin as a starting point only, allowing developers to tailor it precisely to their requirements and optimize its performance and user experience. 79 | 80 | ## Prerequisites 81 | 82 | Before getting started with the WP React Plugin Boilerplate, ensure you have the following: 83 | 84 | - **WordPress Installation:** The plugin requires a WordPress installation set up on your local machine. 85 | 86 | - **Node.js and npm:** Make sure Node.js (which includes npm, the Node Package Manager) is installed on your development environment. You can download and install Node.js from [nodejs.org](https://nodejs.org/en/download/). 87 | 88 | - **WP-CLI:** Required to generate `.pot` files for language translations. [Install WP-CLI](https://make.wordpress.org/cli/handbook/guides/installing/)| [View More](https://wp-cli.org/). 89 | 90 | - **Code Editor:** Use your preferred code editor (e.g., Visual Studio Code, Sublime Text, Atom) to customize and develop the plugin. 91 | 92 | - **Basic Understanding of React:** Familiarity with React.js is recommended as the plugin utilizes React components for its frontend development. 93 | 94 | - **Basic Understanding of WordPress Coding:** Knowledge of WordPress concepts such as PHP coding, hooks, APIs (like REST API), and WordPress functions. 95 | 96 | - **Command Line Interface (CLI):** Comfortable using the command line interface (CLI) for running npm commands and managing the plugin development workflow. 97 | 98 | - **Git (Optional):** If you plan to clone the plugin repository or manage version control, Git should be installed on your system. 99 | 100 | ## GETTING STARTED 101 | 102 | ### 1. Installation 103 | 104 | - Clone the repository to /wp-content/plugins/: 105 | 106 | ```sh 107 | git clone https://github.com/codersantosh/wp-react-plugin-boilerplate.git 108 | ``` 109 | 110 | Or download and upload the plugin files to /wp-content/plugins/wp-react-plugin-boilerplate. 111 | 112 | - Rename the folder name `wp-react-plugin-boilerplate` to your plugin folder. 113 | 114 | ### 2. Development Setup 115 | 116 |
117 | Don't have Node.js + npm installed? You have to install them first. (CLICK TO EXPAND) 118 | 119 | Go to the Node's site [download + install](https://nodejs.org/en/download/) Node on your system. This will install both `Node.js` and `npm`, i.e., node package manager — the command line interface of Node.js. 120 | 121 | You can verify the installation by opening your terminal app and typing... 122 | 123 | ```sh 124 | node -v 125 | # Results into 7.19.1 — or installed version. 126 | 127 | npm -v 128 | # Results into v14.15.1 — or installed version. 129 | ``` 130 | 131 |
132 | 133 | Follow the following steps to add your functionalities to the plugin: 134 | 135 | 1. Navigate to plugin files `/wp-content/plugins/your-renamed-plugin-folder`, and open the terminal app. 136 | 2. Run the `npm install` command to install npm dependencies, and wait sometimes to complete it. 137 | 138 | ### 3. Renaming the Plugin 139 | 140 | You need to rename the plugin folder and file names. Additionally, you should update the constants, variables, classes, text-domain, and functions within the plugin to align with your plugin name. For instance, if your plugin is named `react-settings`, then: 141 | 142 | #### i. Renaming using command 143 | 144 | In the plugin folder, navigate to .bin and open initial-rename.js. Make the following changes: 145 | 146 | - `your-renamed-plugin`, 147 | - `your_renamed_plugin`, 148 | - `YOUR_RENAMED_PLUGIN`, 149 | - `YOUR-RENAMED-PLUGIN`, 150 | - `Your-Renamed-Plugin`, 151 | - `Your_Renamed_Plugin`, 152 | - `YourRenamedPlugin` 153 | 154 | With: 155 | 156 | - `react-settings`, 157 | - `react_settings`, 158 | - `REACT_SETTINGS`, 159 | - `REACT-SETTINGS`, 160 | - `React-Settings`, 161 | - `React_Settings`, 162 | - `ReactSettings` 163 | 164 | Now Run `npm run initial-rename` 165 | 166 | #### ii. OR Manual rename 167 | 168 | - rename the folder from `wp-react-plugin-boilerplate` to `react-settings` 169 | - rename all files from `wp-react-plugin-boilerplate` to `react-settings` PHP, JS and CSS 170 | - change `wp_react_plugin_boilerplate` to `react_settings` 171 | - change `wp-react-plugin-boilerplate` to `react-settings` 172 | - change `Wp_React_Plugin_Boilerplate` to `React_Settings` 173 | - change `WP_REACT_PLUGIN_BOILERPLATE` to `REACT_SETTINGS` 174 | 175 | ### 4. Rename the language file: 176 | 177 | In the plugin folder, open `package.json` and modify the makepot command on line 17. Change `wp-react-plugin-boilerplate.pot` to `react-settings.pot` ( your plugin ). 178 | 179 | ### 5. Activate the Plugin: 180 | 181 | It's safe to activate the plugin at this point. Activate the plugin through the `Plugins` screen in WordPress 182 | 183 | Go to WordPress Dashboard => React Settings and View the Default Landing Page and Settings of the Plugin. 184 | 185 | ### 6. Start Customization and Coding 186 | 187 | Since this is now your own plugin, feel free to customize using your preferred code editor and thoroughly test everything. You have the freedom to add, edit, remove, or update any files, folders, or code within the plugin. However, it's important to be knowledgeable about the changes you make. Follow these steps to begin your development: 188 | 189 | 1. Navigate to plugin files `/wp-content/plugins/your-renamed-plugin-folder`,and open a terminal app. 190 | 2. Run the `npm run start` command to initialize the development of React JS. This command sets up a development server, allowing you to see changes in real time. Use this in the development environment. 191 | 3. Once development is complete, run the `npm run build` command to finalize the development and prepare the plugin for production. This command creates production files. After building, move the production files to the appropriate production directory. 192 | 4. Run the `npm run deploy` command directly to create a production-ready deploy folder. This folder contains all the necessary files for deploying your plugin to a live WordPress site, skipping the need for `npm run build` beforehand. 193 | 194 | ## Folder Information 195 | 196 | WP React Plugin Boilerplate Folder Information 197 | 198 | ```sh 199 | INSIDE: /wp-installatioon-folder/wp-content/plugins/your-renamed-plugin-folder 200 | 201 | ├── .babelrc 202 | ├── .gitignore 203 | ├── LICENSE.txt 204 | ├── index.php 205 | ├── package-lock.json (auto created via NPM) 206 | ├── package.json 207 | ├── readme.md 208 | ├── README.txt 209 | ├── uninstall.php 210 | ├── your-renamed-plugin.php 211 | | 212 | ├── .bin 213 | | ├── copy.js 214 | | ├── initial-rename.js 215 | | ├── make-string.js 216 | | └── replace-atrc.js 217 | | 218 | ├── admin 219 | | ├── class-admin.php 220 | | └── index.php 221 | | 222 | ├── build (auto created via NPM) 223 | | ├── admin 224 | | | ├── admin-rtl.css 225 | | | ├── admin.asset.php 226 | | | ├── admin.css 227 | | | └── admin.js 228 | | | 229 | | └── public 230 | | ├── public-rtl.css 231 | | ├── public.asset.php 232 | | ├── public.css 233 | | └── public.js 234 | | 235 | ├── includes 236 | | ├── api 237 | | | ├── class-api-settings.php 238 | | | ├── class-api.php 239 | | | └── index.php 240 | | ├── class-activator.php 241 | | ├── class-deactivator.php 242 | | ├── class-i18n.php 243 | | ├── class-include.php 244 | | ├── class-loader.php 245 | | ├── functions.php 246 | | ├── index.php 247 | | └── main.php 248 | | 249 | ├── languages 250 | | └── your-renamed-plugin.pot 251 | | 252 | ├── public 253 | | ├── class-public.php 254 | | └── index.php 255 | | 256 | └── src 257 | ├── admin 258 | | └── components 259 | | | ├── atoms 260 | | | | ├── index.js 261 | | | | └── save-settings.js 262 | | | ├── molecules 263 | | | | ├── docs-title.js 264 | | | | └── index.js 265 | | | └── organisms 266 | | | ├── admin-header.js 267 | | | └── index.js 268 | | └── pages 269 | | | ├── landing 270 | | | | └── index.js 271 | | | └── settings 272 | | | ├── pages 273 | | | | ├── advanced.js 274 | | | | ├── index.js 275 | | | | ├── settings1.js 276 | | | | └── settings2.js 277 | | | └── routes.js 278 | | ├── admin.scss 279 | | └── routes.js 280 | | 281 | ├── public 282 | | ├── public.js 283 | | └── public.scss 284 | ├── _mixins.scss 285 | ├── admin.js 286 | ├── prefix-vars.scss 287 | └── public.js 288 | ``` 289 | 290 | ## Changelog 291 | 292 | ### 2.0.1 293 | 294 | - Added: Command to replace the text domain of atrc. 295 | - Updated: readme file. 296 | 297 | ### 2.0.0 298 | 299 | ### Major Update 300 | 301 | - Rewritten: Whole plugin. 302 | - Added: phpcs:ignore Class file names should be based on the class name with "class-" prepended. 303 | - Added: [Atrc (atrc) - Atomic React Components](https://github.com/codersantosh/atrc) 304 | - Added: [Atomic CSS](https://github.com/codersantosh/atomic-css) 305 | - Added: npm admin and public scripts 306 | - Added: npm makepot and copy scripts 307 | - Added: npm deploy script 308 | - Added: npm initial-rename script 309 | - Updated: UI and UX 310 | - Updated: Custom settings API 311 | - Removed: [Uses Inbuilt WordPress Settings API](https://github.com/codersantosh/wp-react-plugin-boilerplate/issues/8) 312 | 313 | ### 1.0.1 314 | 315 | #### Major Update 316 | 317 | - Added: Uses React Router, Context, and Reducer 318 | - Added: Atomic Design Methodology 319 | - Added: [AT Grid](https://github.com/codersantosh/at-grid) 320 | - Added: Uses Inbuilt WordPress Settings API 321 | - Added: Settings via register_setting 322 | - Updated: UI and UX 323 | - Removed: Custom API and Custom Sanitization Functions 324 | 325 | ### 1.0.0 326 | 327 | - Initial Release 328 | 329 | ## Contributing 330 | 331 | Thank you for your interest in contributing to Project WP React Plugin Boilerplate. To submit your changes, please follow the steps outlined below. 332 | 333 | 1. **Fork the Repository:** Click on the "Fork" button on the top right corner of the repository page to create your fork. 334 | 335 | 2. **Clone your Fork:** Clone your forked repository to your local machine using the following command: 336 | 337 | ```sh 338 | git clone https://github.com/your-username/wp-react-plugin-boilerplate.git 339 | ``` 340 | 341 | 3. **Create a Feature Branch:** Create a new branch for your feature or bug fix: 342 | 343 | ```sh 344 | git checkout -b my-new-feature 345 | ``` 346 | 347 | 4. **Make Changes:** Add your changes to the project. You can use the following command to stage all changes: 348 | 349 | ```sh 350 | git add . 351 | ``` 352 | 353 | 5. **Commit Changes:** Commit your changes with a descriptive commit message: 354 | 355 | ```sh 356 | git commit -a m 'Add some feature' 357 | ``` 358 | 359 | 6. **Push to your Branch:** Push your changes to the branch you created on your fork: 360 | 361 | ```sh 362 | git push origin my-new-feature 363 | ``` 364 | 365 | 7. **Submit a Pull Request:** Go to the Pull Requests tab of the original repository and click on "New Pull Request." Provide a clear title and description for your changes, and submit the pull request. 366 | 367 | Thank you for contributing to this project! 368 | 369 | ## Authors 370 | 371 | - **Santosh Kunwar** - [codersantosh](https://twitter.com/codersantosh) 372 | 373 | See also the list of [contributors](https://github.com/codersantosh/wp-react-plugin-boilerplate/graphs/contributors) who participated in this project. 374 | 375 | ## Recommendations 376 | 377 | - [ATOMIC WP CUSTOM TABLE AND QUERY](https://github.com/codersantosh/atomic-wp-custom-table-and-query) 378 | - [Atrc (atrc) - Atomic React Components](https://www.npmjs.com/package/atrc) 379 | - [Atomic CSS](https://github.com/codersantosh/atomic-css) 380 | 381 | ## License & Attribution 382 | 383 | - GPLv2 or later © [Santosh Kunwar](https://twitter.com/codersantosh). 384 | 385 | I would like to thank all the React.js team, Gutenberg Team, WordPress Core Contributors, WordPress Plugin Boilerplate teams and My friends for motivating me to create the starter plugin. 386 | 387 | ## About Me 388 | 389 | I just love WordPress more… 390 | 391 | - [![CoderSantosh on Twitter](https://img.shields.io/twitter/follow/codersantosh.svg)](https://twitter.com/codersantosh/) 392 | - WordPress Profile 393 | 394 | ### Recent Projects 395 | 396 | Gutentor - WordPress Page Building Blocks - Page Builder for Gutenberg 397 | -------------------------------------------------------------------------------- /src/_mixins.scss: -------------------------------------------------------------------------------- 1 | //––––––––––––––––––––––––––––––––––– 2 | // MEDIA QUERIES 3 | //––––––––––––––––––––––––––––––––––– 4 | 5 | // A map of breakpoints. 6 | $breakpoints: (xs: 576px, 7 | sm: 768px, 8 | md: 992px, 9 | lg: 1200px, 10 | xl: 1500px, 11 | xxl: 1700px); 12 | 13 | 14 | // 15 | // RESPOND ABOVE 16 | //–––––––––––––––––––––––––––––––––––––––––––––––––– 17 | 18 | // @include respond-above(sm) {} 19 | @mixin respond-above($breakpoint) { 20 | 21 | // If the breakpoint exists in the map. 22 | @if map-has-key($breakpoints, $breakpoint) { 23 | 24 | // Get the breakpoint value. 25 | $breakpoint-value: map-get($breakpoints, $breakpoint); 26 | 27 | // Write the media query. 28 | @media (min-width: $breakpoint-value) { 29 | @content; 30 | } 31 | 32 | // If the breakpoint doesn't exist in the map. 33 | } 34 | 35 | @else { 36 | 37 | // Log a warning. 38 | @warn 'Invalid breakpoint: #{$breakpoint}.'; 39 | } 40 | } 41 | 42 | 43 | // 44 | // RESPOND BELOW 45 | //–––––––––––––––––––––––––––––––––––––––––––––––––– 46 | 47 | // @include respond-below(sm) {} 48 | @mixin respond-below($breakpoint) { 49 | 50 | // If the breakpoint exists in the map. 51 | @if map-has-key($breakpoints, $breakpoint) { 52 | 53 | // Get the breakpoint value. 54 | $breakpoint-value: map-get($breakpoints, $breakpoint); 55 | 56 | // Write the media query. 57 | @media (max-width: ($breakpoint-value - 1)) { 58 | @content; 59 | } 60 | 61 | // If the breakpoint doesn't exist in the map. 62 | } 63 | 64 | @else { 65 | 66 | // Log a warning. 67 | @warn 'Invalid breakpoint: #{$breakpoint}.'; 68 | } 69 | } 70 | 71 | 72 | // 73 | // RESPOND BETWEEN 74 | //–––––––––––––––––––––––––––––––––––––––––––––––––– 75 | 76 | // @include respond-between(sm, md) {} 77 | @mixin respond-between($lower, $upper) { 78 | 79 | // If both the lower and upper breakpoints exist in the map. 80 | @if map-has-key($breakpoints, $lower) and map-has-key($breakpoints, $upper) { 81 | 82 | // Get the lower and upper breakpoints. 83 | $lower-breakpoint: map-get($breakpoints, $lower); 84 | $upper-breakpoint: map-get($breakpoints, $upper); 85 | 86 | // Write the media query. 87 | @media (min-width: $lower-breakpoint) and (max-width: ($upper-breakpoint - 1)) { 88 | @content; 89 | } 90 | 91 | // If one or both of the breakpoints don't exist. 92 | } 93 | 94 | @else { 95 | 96 | // If lower breakpoint is invalid. 97 | @if (map-has-key($breakpoints, $lower)==false) { 98 | 99 | // Log a warning. 100 | @warn 'Your lower breakpoint was invalid: #{$lower}.'; 101 | } 102 | 103 | // If upper breakpoint is invalid. 104 | @if (map-has-key($breakpoints, $upper)==false) { 105 | 106 | // Log a warning. 107 | @warn 'Your upper breakpoint was invalid: #{$upper}.'; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /src/admin/admin.scss: -------------------------------------------------------------------------------- 1 | @import '../prefix-vars.scss'; 2 | @import '../mixins'; 3 | @import '../../node_modules/atrc/build/index.css'; 4 | @import '../../node_modules/atrc/build/wp-admin.css'; -------------------------------------------------------------------------------- /src/admin/components/atoms/index.js: -------------------------------------------------------------------------------- 1 | export { default as SaveSettings } from './save-settings'; 2 | -------------------------------------------------------------------------------- /src/admin/components/atoms/save-settings.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | import { useContext } from '@wordpress/element'; 4 | 5 | /* Library */ 6 | 7 | /*Atrc*/ 8 | import { AtrcButtonSaveTemplate1, AtrcFooterTemplate1 } from 'atrc'; 9 | 10 | /* Inbuilt */ 11 | import { AtrcReduxContextData } from '../../routes'; 12 | 13 | /*Local*/ 14 | const SaveSettings = ({ onClick }) => { 15 | const data = useContext(AtrcReduxContextData); 16 | const { dbIsLoading, dbCanSave, dbSettings, dbSaveSettings } = data; 17 | 18 | return ( 19 | 20 | dbSaveSettings(dbSettings)} 30 | /> 31 | 32 | ); 33 | }; 34 | 35 | export default SaveSettings; 36 | -------------------------------------------------------------------------------- /src/admin/components/molecules/docs-title.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | 4 | /* Library */ 5 | 6 | /*Atrc*/ 7 | import { AtrcTitleTemplate2 } from 'atrc'; 8 | 9 | /* Inbuilt */ 10 | 11 | /*Local*/ 12 | const DocsTitle = ({ onClick }) => { 13 | return ( 14 | ', 21 | }, 22 | onClick: () => onClick(), 23 | variant: 'danger', 24 | className: 'at-btn-close at-flx at-al-itm-ctr', 25 | }, 26 | ]} 27 | /> 28 | ); 29 | }; 30 | 31 | export default DocsTitle; 32 | -------------------------------------------------------------------------------- /src/admin/components/molecules/index.js: -------------------------------------------------------------------------------- 1 | export { default as DocsTitle } from './docs-title'; 2 | -------------------------------------------------------------------------------- /src/admin/components/organisms/admin-header.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | 4 | import { useContext } from '@wordpress/element'; 5 | 6 | /* Library */ 7 | import classNames from 'classnames'; 8 | 9 | /*Atrc*/ 10 | import { AtrcButton, AtrcWrap, AtrcHeaderTemplate1 } from 'atrc'; 11 | 12 | /* Inbuilt */ 13 | import { AtrcReduxContextData } from '../../routes'; 14 | 15 | /*Local*/ 16 | const AdminHeader = () => { 17 | const data = useContext(AtrcReduxContextData); 18 | 19 | const { lsSettings, lsSaveSettings } = data; 20 | 21 | const primaryNav = [ 22 | { 23 | to: '/', 24 | children: __('Getting started', 'wp-react-plugin-boilerplate'), 25 | end: true, 26 | }, 27 | { 28 | to: '/settings', 29 | children: __('Settings', 'wp-react-plugin-boilerplate'), 30 | }, 31 | ]; 32 | 33 | return ( 34 | ( 43 | 44 | lsSaveSettings(null)}> 47 | {__( 48 | 'Show all hidden informations, notices and documentations ', 49 | 'wp-react-plugin-boilerplate' 50 | )} 51 | 52 | 53 | )} 54 | /> 55 | ); 56 | }; 57 | 58 | export default AdminHeader; 59 | -------------------------------------------------------------------------------- /src/admin/components/organisms/index.js: -------------------------------------------------------------------------------- 1 | export { default as AdminHeader } from "./admin-header"; 2 | -------------------------------------------------------------------------------- /src/admin/index.js: -------------------------------------------------------------------------------- 1 | /* *********===================== Setup store ======================********* */ 2 | import { AtrcApis, AtrcStore, AtrcRegisterStore } from 'atrc/build/data'; 3 | 4 | AtrcApis.baseUrl({ 5 | //don't change atrc-global-api-base-url 6 | key: 'atrc-global-api-base-url', 7 | // eslint-disable-next-line no-undef 8 | url: WpReactPluginBoilerplateLocalize.rest_url, 9 | }); 10 | 11 | /* Settings */ 12 | AtrcApis.register({ 13 | key: 'settings', 14 | path: 'wp-react-plugin-boilerplate/v1/settings', 15 | type: 'settings', 16 | }); 17 | 18 | /* Settings Local for user preferance work with Window: localStorage property */ 19 | AtrcStore.register({ 20 | key: 'WpReactPluginBoilerplateLocal', 21 | type: 'localStorage', 22 | }); 23 | 24 | // eslint-disable-next-line no-undef 25 | AtrcApis.xWpNonce(WpReactPluginBoilerplateLocalize.nonce); 26 | AtrcRegisterStore(WpReactPluginBoilerplateLocalize.store); 27 | 28 | import './routes'; 29 | 30 | -------------------------------------------------------------------------------- /src/admin/pages/landing/index.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { useContext } from '@wordpress/element'; 3 | 4 | /* Library */ 5 | import { cloneDeep } from 'lodash'; 6 | 7 | /*Atrc*/ 8 | import { AtrcLandingTemplate1 } from 'atrc'; 9 | 10 | /* Inbuilt */ 11 | import { AtrcReduxContextData } from '../../routes'; 12 | 13 | /* Local */ 14 | const Landing = () => { 15 | const data = useContext(AtrcReduxContextData); 16 | const { lsSettings, lsSaveSettings } = data; 17 | const { white_label: dynamicWhitelabel } = WpReactPluginBoilerplateLocalize; 18 | const { dashboard, landingPage } = dynamicWhitelabel; 19 | 20 | const whiteLabel = {}; 21 | /* Notice */ 22 | if (dashboard.notice) { 23 | whiteLabel.notice = { 24 | on: lsSettings.gs1, 25 | text: dashboard.notice, 26 | onRemove: () => { 27 | const localStorageClone = cloneDeep(lsSettings); 28 | localStorageClone.gs1 = !localStorageClone.gs1; 29 | lsSaveSettings(localStorageClone); 30 | }, 31 | }; 32 | } 33 | 34 | if (landingPage) { 35 | if (landingPage.banner) { 36 | /*Banner */ 37 | whiteLabel.banner = landingPage.banner; 38 | } 39 | if (landingPage.identity) { 40 | /*Identity */ 41 | whiteLabel.identity = landingPage.identity; 42 | } 43 | if (landingPage.contact) { 44 | /*Contact */ 45 | whiteLabel.contact = landingPage.contact; 46 | } 47 | if (landingPage.bannerColumns) { 48 | /*Banner columns */ 49 | whiteLabel.bannerColumns = landingPage.bannerColumns; 50 | } 51 | if (landingPage.normalColumns) { 52 | /*Normal columns */ 53 | whiteLabel.normalColumns = landingPage.normalColumns; 54 | } 55 | if (landingPage.topicLinks) { 56 | /*Topic links and columns */ 57 | whiteLabel.topicLinks = landingPage.topicLinks; 58 | } 59 | if (landingPage.changelog) { 60 | /*Topic links and columns */ 61 | whiteLabel.changelog = landingPage.changelog; 62 | } 63 | } 64 | 65 | return ; 66 | }; 67 | 68 | export default Landing; 69 | -------------------------------------------------------------------------------- /src/admin/pages/settings/pages/advanced.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | import { useContext } from '@wordpress/element'; 4 | 5 | /* Library */ 6 | import classNames from 'classnames'; 7 | import { cloneDeep } from 'lodash'; 8 | 9 | /*Atrc*/ 10 | import { 11 | AtrcText, 12 | AtrcControlToggle, 13 | AtrcWireFrameContentSidebar, 14 | AtrcWireFrameHeaderContentFooter, 15 | AtrcPrefix, 16 | AtrcPanelBody, 17 | AtrcPanelRow, 18 | AtrcContent, 19 | AtrcTitleTemplate1, 20 | } from 'atrc'; 21 | 22 | /* Inbuilt */ 23 | import { AtrcReduxContextData } from '../../../routes'; 24 | import { DocsTitle } from '../../../components/molecules'; 25 | 26 | /*Local*/ 27 | const MainContent = () => { 28 | const data = useContext(AtrcReduxContextData); 29 | 30 | const { dbSettings, dbUpdateSetting } = data; 31 | 32 | const { deleteAll = false } = dbSettings; 33 | 34 | return ( 35 | 36 | 37 | dbUpdateSetting('deleteAll', !deleteAll)} 44 | /> 45 | 46 | 47 | ); 48 | }; 49 | 50 | const Documentation = () => { 51 | const data = useContext(AtrcReduxContextData); 52 | 53 | const { lsSettings, lsSaveSettings } = data; 54 | 55 | return ( 56 | { 63 | const localStorageClone = cloneDeep(lsSettings); 64 | localStorageClone.bmSaDocs1 = !localStorageClone.bmSaDocs1; 65 | lsSaveSettings(localStorageClone); 66 | }} 67 | /> 68 | } 69 | renderContent={ 70 | <> 71 | 78 | 81 | {__( 82 | 'Enabling this option will erase all settings associated with the plugin from the WordPress options table. However, please note that the selected page will not be deleted from Pages.', 83 | 'wp-react-plugin-boilerplate' 84 | )} 85 | 86 | 87 | 90 | 93 | {__( 94 | 'If you anticipate using the `Login feature` in the future, no need to activate it.', 95 | 'wp-react-plugin-boilerplate' 96 | )} 97 | 98 | 99 | 100 | } 101 | allowHeaderRow={false} 102 | allowHeaderCol={false} 103 | allowContentRow={false} 104 | allowContentCol={false} 105 | /> 106 | ); 107 | }; 108 | 109 | const Settings = () => { 110 | const data = useContext(AtrcReduxContextData); 111 | const { lsSettings } = data; 112 | 113 | const { bmSaDocs1 } = lsSettings; 114 | 115 | return ( 116 | 122 | } 123 | renderContent={ 124 | } 132 | renderSidebar={!bmSaDocs1 ? : null} 133 | contentProps={{ 134 | contentCol: bmSaDocs1 ? 'at-col-12' : 'at-col-7', 135 | }} 136 | sidebarProps={{ 137 | sidebarCol: 'at-col-5', 138 | }} 139 | /> 140 | } 141 | allowHeaderRow={false} 142 | allowHeaderCol={false} 143 | allowContentRow={false} 144 | allowContentCol={false} 145 | /> 146 | ); 147 | }; 148 | 149 | export default Settings; 150 | -------------------------------------------------------------------------------- /src/admin/pages/settings/pages/index.js: -------------------------------------------------------------------------------- 1 | export { default as Settings1 } from './settings1'; 2 | export { default as Settings2 } from './settings2'; 3 | export { default as Advanced } from './advanced'; 4 | -------------------------------------------------------------------------------- /src/admin/pages/settings/pages/settings1.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | import { useContext } from '@wordpress/element'; 4 | 5 | /* Library */ 6 | import classNames from 'classnames'; 7 | import { cloneDeep } from 'lodash'; 8 | 9 | /*Atrc*/ 10 | import { 11 | AtrcText, 12 | AtrcControlText, 13 | AtrcWireFrameContentSidebar, 14 | AtrcWireFrameHeaderContentFooter, 15 | AtrcPrefix, 16 | AtrcPanelBody, 17 | AtrcPanelRow, 18 | AtrcContent, 19 | AtrcTitleTemplate1 20 | } from 'atrc'; 21 | 22 | /* Inbuilt */ 23 | import { AtrcReduxContextData } from '../../../routes'; 24 | import { DocsTitle } from '../../../components/molecules'; 25 | 26 | /*Local*/ 27 | const MainContent = () => { 28 | const data = useContext(AtrcReduxContextData); 29 | 30 | const { dbSettings, dbUpdateSetting } = data; 31 | 32 | const { setting1 = '', setting2 = '' } = dbSettings; 33 | 34 | return ( 35 | 36 | 37 | 42 | dbUpdateSetting('setting1', newVal) 43 | } 44 | 45 | /> 46 | 47 | 48 | 53 | dbUpdateSetting('setting2', newVal) 54 | } 55 | 56 | /> 57 | 58 | 59 | ); 60 | }; 61 | 62 | const Documentation = () => { 63 | const data = useContext(AtrcReduxContextData); 64 | 65 | const { lsSettings, lsSaveSettings } = data; 66 | 67 | return ( 68 | { 75 | const localStorageClone = cloneDeep(lsSettings); 76 | localStorageClone.bmSaDocs1 = !localStorageClone.bmSaDocs1; 77 | lsSaveSettings(localStorageClone); 78 | }} 79 | /> 80 | } 81 | renderContent={ 82 | <> 83 | 90 | 93 | {__( 94 | 'FAQ Answer 1', 95 | 'wp-react-plugin-boilerplate' 96 | )} 97 | 98 | 99 | 102 | 105 | {__( 106 | 'FAQ Answer 2', 107 | 'wp-react-plugin-boilerplate' 108 | )} 109 | 110 | 111 | 112 | } 113 | allowHeaderRow={false} 114 | allowHeaderCol={false} 115 | allowContentRow={false} 116 | allowContentCol={false} 117 | /> 118 | ); 119 | }; 120 | 121 | const Settings = () => { 122 | const data = useContext(AtrcReduxContextData); 123 | const { lsSettings } = data; 124 | 125 | const { bmSaDocs1 } = lsSettings; 126 | 127 | return ( 128 | 134 | } 135 | renderContent={ 136 | } 144 | renderSidebar={!bmSaDocs1 ? : null} 145 | contentProps={{ 146 | contentCol: bmSaDocs1 ? 'at-col-12' : 'at-col-7', 147 | }} 148 | sidebarProps={{ 149 | sidebarCol: 'at-col-5', 150 | }} 151 | /> 152 | } 153 | allowHeaderRow={false} 154 | allowHeaderCol={false} 155 | allowContentRow={false} 156 | allowContentCol={false} 157 | /> 158 | ); 159 | }; 160 | 161 | export default Settings; 162 | -------------------------------------------------------------------------------- /src/admin/pages/settings/pages/settings2.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | import { useContext } from '@wordpress/element'; 4 | 5 | /* Library */ 6 | import classNames from 'classnames'; 7 | import { cloneDeep } from 'lodash'; 8 | 9 | /*Atrc*/ 10 | import { 11 | AtrcText, 12 | AtrcControlToggle, 13 | AtrcWireFrameContentSidebar, 14 | AtrcWireFrameHeaderContentFooter, 15 | AtrcControlSelect, 16 | AtrcPrefix, 17 | AtrcPanelBody, 18 | AtrcPanelRow, 19 | AtrcContent, 20 | AtrcTitleTemplate1 21 | } from 'atrc'; 22 | 23 | /* Inbuilt */ 24 | import { AtrcReduxContextData } from '../../../routes'; 25 | import { DocsTitle } from '../../../components/molecules'; 26 | 27 | /*Local*/ 28 | const MainContent = () => { 29 | const data = useContext(AtrcReduxContextData); 30 | 31 | const { dbSettings, dbUpdateSetting } = data; 32 | 33 | const { setting3 = false, setting4 = false, setting5 = 'option-1' } = dbSettings; 34 | 35 | return ( 36 | 37 | 38 | dbUpdateSetting('setting3', !setting3)} 45 | /> 46 | 47 | 48 | 49 | dbUpdateSetting('setting4', !setting4)} 56 | /> 57 | 58 | 59 | 60 | 74 | dbUpdateSetting('setting5', newVal) 75 | } 76 | /> 77 | 78 | 79 | 80 | ); 81 | }; 82 | 83 | const Documentation = () => { 84 | const data = useContext(AtrcReduxContextData); 85 | 86 | const { lsSettings, lsSaveSettings } = data; 87 | 88 | return ( 89 | { 96 | const localStorageClone = cloneDeep(lsSettings); 97 | localStorageClone.bmSaDocs1 = !localStorageClone.bmSaDocs1; 98 | lsSaveSettings(localStorageClone); 99 | }} 100 | /> 101 | } 102 | renderContent={ 103 | <> 104 | 111 | 114 | {__( 115 | 'FAQ Answer 3', 116 | 'wp-react-plugin-boilerplate' 117 | )} 118 | 119 | 120 | 123 | 126 | {__( 127 | 'FAQ Answer 4', 128 | 'wp-react-plugin-boilerplate' 129 | )} 130 | 131 | 132 | 133 | } 134 | allowHeaderRow={false} 135 | allowHeaderCol={false} 136 | allowContentRow={false} 137 | allowContentCol={false} 138 | /> 139 | ); 140 | }; 141 | 142 | const Settings = () => { 143 | const data = useContext(AtrcReduxContextData); 144 | const { lsSettings } = data; 145 | 146 | const { bmSaDocs1 } = lsSettings; 147 | 148 | return ( 149 | 155 | } 156 | renderContent={ 157 | } 165 | renderSidebar={!bmSaDocs1 ? : null} 166 | contentProps={{ 167 | contentCol: bmSaDocs1 ? 'at-col-12' : 'at-col-7', 168 | }} 169 | sidebarProps={{ 170 | sidebarCol: 'at-col-5', 171 | }} 172 | /> 173 | } 174 | allowHeaderRow={false} 175 | allowHeaderCol={false} 176 | allowContentRow={false} 177 | allowContentCol={false} 178 | /> 179 | ); 180 | }; 181 | 182 | export default Settings; 183 | -------------------------------------------------------------------------------- /src/admin/pages/settings/routes.js: -------------------------------------------------------------------------------- 1 | /* WordPress */ 2 | import { __ } from '@wordpress/i18n'; 3 | import { useContext } from '@wordpress/element'; 4 | 5 | /* Library */ 6 | import { isEmpty } from 'lodash'; 7 | 8 | /*Atrc*/ 9 | import { 10 | AtrcRoute, 11 | AtrcRoutes, 12 | AtrcNavigate, 13 | AtrcNav, 14 | AtrcWireFrameSidebarContent, 15 | } from 'atrc'; 16 | 17 | /*Inbuilt*/ 18 | import { Settings1, Settings2, Advanced } from './pages'; 19 | import { AtrcReduxContextData } from '../../routes'; 20 | import { SaveSettings } from '../../components/atoms'; 21 | 22 | /*Local*/ 23 | const SettingsRouters = () => { 24 | return ( 25 | <> 26 | 27 | } 31 | /> 32 | } 36 | /> 37 | } 41 | /> 42 | 49 | } 50 | /> 51 | 52 | 53 | 54 | ); 55 | }; 56 | 57 | const InitSettings = () => { 58 | const data = useContext(AtrcReduxContextData); 59 | const { dbSettings } = data; 60 | 61 | if (isEmpty(dbSettings)) { 62 | return null; 63 | } 64 | return ( 65 | 89 | } 90 | renderContent={} 91 | contentProps={{ 92 | tag: 'div', 93 | contentCol: 'at-col-10', 94 | }} 95 | sidebarProps={{ 96 | sidebarCol: 'at-col-2', 97 | }} 98 | /> 99 | ); 100 | }; 101 | 102 | export default InitSettings; 103 | -------------------------------------------------------------------------------- /src/admin/routes.js: -------------------------------------------------------------------------------- 1 | /*CSS*/ 2 | import './admin.scss'; 3 | 4 | /* WordPress */ 5 | import { render, createContext, useContext } from '@wordpress/element'; 6 | 7 | /* Library */ 8 | import { map, isEmpty } from 'lodash'; 9 | 10 | /*Atrc*/ 11 | import { 12 | AtrcHashRouter, 13 | AtrcRoute, 14 | AtrcRoutes, 15 | AtrcWrap, 16 | AtrcNotice, 17 | AtrcWrapFloating, 18 | AtrcMain 19 | } from 'atrc'; 20 | 21 | import { AtrcApplyWithSettings } from 'atrc/build/data'; 22 | 23 | /*Inbuilt*/ 24 | import AdminHeader from './components/organisms/admin-header'; 25 | import Initlanding from './pages/landing'; 26 | import InitSettings from './pages/settings/routes'; 27 | 28 | /* Local */ 29 | 30 | /* ==============Create Local Storage and Database Settings Context================== */ 31 | export const AtrcReduxContextData = createContext(); 32 | 33 | const AdminRoutes = () => { 34 | const data = useContext(AtrcReduxContextData); 35 | const { dbNotices, dbRemoveNotice } = data; 36 | 37 | return ( 38 | <> 39 | 40 | 41 | 42 | } 45 | /> 46 | } 50 | /> 51 | 52 | {/*Notice is common for settings*/} 53 | {!isEmpty(dbNotices) ? ( 54 | 55 | {map(dbNotices, (value, key) => ( 56 | dbRemoveNotice(key)} 60 | onRemove={() => dbRemoveNotice(key)}> 61 | {value.message} 62 | 63 | ))} 64 | 65 | ) : null} 66 | 67 | 68 | ); 69 | }; 70 | 71 | /* Init actual WordPress settings */ 72 | const InitDatabaseSettings = (props) => { 73 | const { 74 | isLoading, 75 | canSave, 76 | settings, 77 | updateSetting, 78 | saveSettings, 79 | notices, 80 | removeNotice, 81 | lsSettings, 82 | lsUpdateSetting, 83 | lsSaveSettings, 84 | } = props; 85 | 86 | const dbProps = { 87 | dbIsLoading: isLoading, 88 | dbCanSave: canSave, 89 | dbSettings: settings, 90 | dbUpdateSetting: updateSetting, 91 | dbSaveSettings: saveSettings, 92 | dbNotices: notices, 93 | dbRemoveNotice: removeNotice, 94 | lsSettings: lsSettings, 95 | lsUpdateSetting: lsUpdateSetting, 96 | lsSaveSettings: lsSaveSettings, 97 | }; 98 | return ( 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | ); 109 | }; 110 | const InitDataBaseSettingsWithHoc = AtrcApplyWithSettings(InitDatabaseSettings); 111 | 112 | /* Init local storage settings */ 113 | const InitLocalStorageSettings = (props) => { 114 | const { settings, updateSetting, saveSettings } = props; 115 | const defaultSettings = { 116 | gs1: true /* getting started 1 */, 117 | }; 118 | return ( 119 | 126 | ); 127 | }; 128 | const InitLocalStorageSettingsWithHoc = AtrcApplyWithSettings( 129 | InitLocalStorageSettings 130 | ); 131 | 132 | document.addEventListener('DOMContentLoaded', () => { 133 | // Check if the root element exists in the DOM 134 | const rootElement = document.getElementById(WpReactPluginBoilerplateLocalize.root_id); 135 | 136 | if (rootElement) { 137 | // Render the component into the root element 138 | render( 139 | , 143 | rootElement 144 | ); 145 | } 146 | }); 147 | -------------------------------------------------------------------------------- /src/prefix-vars.scss: -------------------------------------------------------------------------------- 1 | //ClassesPrefix 2 | //Change it according to your plugin name 3 | // wrpb wp-react-plugin-boilerplate 4 | $appPrefix: '.wrpb'; 5 | 6 | //Root variable Prefix from atomic css, we are overiting css variables values 7 | // dont change it 8 | $varPrefix: '--at'; -------------------------------------------------------------------------------- /src/public/index.js: -------------------------------------------------------------------------------- 1 | /*CSS*/ 2 | import './public.scss'; 3 | 4 | /* Write own JS */ 5 | console.log('Hello from public') -------------------------------------------------------------------------------- /src/public/public.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codersantosh/wp-react-plugin-boilerplate/27be0438715b622f63d729543d8bb3d73d465039/src/public/public.scss -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | run(); 85 | } 86 | wp_react_plugin_boilerplate_run(); 87 | --------------------------------------------------------------------------------