آموزش ساخت افزونه وردپرس قسمت 2
در بخش اول این آموزش، اصول پایه ساختن افزونه وردپرس را با استفاده از Boilerplate افزونه وردپرس و generator دستی آموزش دادیم و یادگرفتیم که چگونه انواع ورودی های اولیه اضافه، حذف و ذخیره کنیم. در صورتی که آن بخش را از دست داده اید، به چگونه افزونه وردپرس بسازیم (بخش اول) بروید و آن را مطالعه کنید.
در بخش دوم این مطالب را پوشش خواهیم داد:
- بین المللی کردن پلاگین مان
- اضافه کردن ورودی های مختلف مانند color picker یا file upload
- تقسیم بندی صفحه به multiple tabs
- ایجاد کردن functions که در واقع کارهایی را در front/back-end انجام میدهند.
- تست نهایی پلاگین مان
- و سپس ارسال پلاگین مان به تیم وردپرس برای بررسی
ما بر روی کدهای پایه بخش یک کار خواهیم کرد، بنابراین اگر بر روی آنها کار نکرده اید؛ حتما مطلب قبلی را مطالعه نمایید.
افزونه تان را قابل ترجمه کنید (بین المللی کردن یا il18n)
قبل از اینکه بر روی کدها کار کنیم، اجازه بدهید توضیح بدهم که چرا قابل ترجمه شدن افزونه تان اهمیت دارد.
با اضافه کردن یک پلاگین به منبع وردپرس، شما جزئی از جامعه وردپرس می شوید و این موفقیت بزرگی است. بنابراین، شما می توانید درک کنید که طیف وسیعی از مردم از کشورهای مختلف ممکن است از آن استفاده کنند. برخی از این افراد ممکن است به زبان انگلیسی و یا زبان اصلی مسلط نباشند و این باعث می شود تا شما افزونه تان را به راحتی قابل ترجمه کنید بدون آنکه نیاز داشته باشید برنامه نویسی اصلی (core coding) آن را دستکاری کنید.
اگر از بخش اول به خاطر بیاورید boilerplate افزونه شما با یک پوشه زبان همراه است که فایل های زبان پلاگین شما در آنجا قرار دارد. نمی خواهم روند ترجمه را بطور کامل در اینجا توضیح بدهم، فقط می دانم که برخی از برنامه های کاربردی مانند poedit در اینجا هستند که می توانند به ما کمک کنند.
اجازه بدهید یک سری تغییراتی در کدهای موجود ایجاد کنیم تا poedit بتواند تمام ردیف های قابل ترجمه مان (translatable strings) را پیدا کند.
اساسا، ما خیلی اینجا را تغییر ندادیم، فقط همه hard-coded strings را با این ها پوشش دادیم:
شاید این مطالب هم دوست داشته باشید
1 |
<?php _e('our string', $this->plugin_name);?> |
تنها کاری که می کند echo(_e) our string است و آنرا به افزونه مان نسبت می دهد ($this->plugin_name)
کد زیر را ببینید تا تغییر کامل کدها را متوجه شوید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
<?php /** * * admin/partials/wp-cbf-admin-display.php * **/ /** * Provide a admin area view for the plugin * * This file is used to markup the admin-facing aspects of the plugin. * * @link http://lostwebdesigns.com * @since 1.0.0 * * @package Wp_Cbf * @subpackage Wp_Cbf/admin/partials */ ?> <!-- This file should primarily consist of HTML with a little bit of PHP. --> <div class="wrap"> <h2><?php echo esc_html( get_admin_page_title() ); ?></h2> <h2 class="nav-tab-wrapper">Clean up</h2> <form method="post" name="cleanup_options" action="options.php"> <?php //Grab all options $options = get_option($this->plugin_name); // Cleanup $cleanup = $options['cleanup']; $comments_css_cleanup = $options['comments_css_cleanup']; $gallery_css_cleanup = $options['gallery_css_cleanup']; $body_class_slug = $options['body_class_slug']; $jquery_cdn = $options['jquery_cdn']; $cdn_provider = $options['cdn_provider']; ?> <?php settings_fields( $this->plugin_name ); do_settings_sections( $this->plugin_name ); ?> <!-- remove some meta and generators from the <head> --> <fieldset> <legend class="screen-reader-text"><span><?php _e('Clean WordPress head section', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-cleanup"> <input type="checkbox" id="<?php echo $this->plugin_name;?>-cleanup" name="<?php echo $this->plugin_name;?>[cleanup]" value="1" <?php checked( $cleanup, 1 ); ?> /> <span><?php esc_attr_e( 'Clean up the head section', $this->plugin_name ); ?></span> </label> </fieldset> <!-- remove injected CSS from comments widgets --> <fieldset> <legend class="screen-reader-text"><span>Remove Injected CSS for comment widget</span></legend> <label for="<?php echo $this->plugin_name;?>-comments_css_cleanup"> <input type="checkbox" id="<?php echo $this->plugin_name;?>-comments_css_cleanup" name="<?php echo $this->plugin_name;?>[comments_css_cleanup]" value="1" <?php checked( $comments_css_cleanup, 1 ); ?> /> <span><?php esc_attr_e( 'Remove Injected CSS for comment widget', $this->plugin_name ); ?></span> </label> </fieldset> <!-- remove injected CSS from gallery --> <fieldset> <legend class="screen-reader-text"><span>Remove Injected CSS for galleries</span></legend> <label for="<?php echo $this->plugin_name;?>-gallery_css_cleanup"> <input type="checkbox" id="<?php echo $this->plugin_name;?>-gallery_css_cleanup" name="<?php echo $this->plugin_name;?>[gallery_css_cleanup]" value="1" <?php checked( $gallery_css_cleanup, 1 ); ?> /> <span><?php esc_attr_e( 'Remove Injected CSS for galleries', $this->plugin_name ); ?></span> </label> </fieldset> <!-- add post,page or product slug class to body class --> <fieldset> <legend class="screen-reader-text"><span><?php _e('Add Post, page or product slug to body class', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-body_class_slug"> <input type="checkbox" id="<?php echo $this->plugin_name;?>-body_class_slug" name="<?php echo $this->plugin_name;?>[body_class_slug]" value="1" <?php checked( $body_class_slug, 1 ); ?> /> <span><?php esc_attr_e('Add Post slug to body class', $this->plugin_name);?></span> </label> </fieldset> <!-- load jQuery from CDN --> <fieldset> <legend class="screen-reader-text"><span><?php _e('Load jQuery from CDN instead of the basic wordpress script', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-jquery_cdn"> <input type="checkbox" id="<?php echo $this->plugin_name;?>-jquery_cdn" name="<?php echo $this->plugin_name;?>[jquery_cdn]" value="1" <?php checked($jquery_cdn,1);?>/> <span><?php esc_attr_e('Load jQuery from CDN', $this->plugin_name);?></span> </label> <fieldset class="<?php if(1 != $jquery_cdn) echo 'hidden';?>"> <p>You can choose your own cdn provider and jQuery version(default will be Google Cdn and version 1.11.1)-Recommended CDN are <a href="https://cdnjs.com/libraries/jquery">CDNjs</a>, <a href="https://code.jquery.com/jquery/">jQuery official CDN</a>, <a href="https://developers.google.com/speed/libraries/#jquery">Google CDN</a> and <a href="http://www.asp.net/ajax/cdn#jQuery_Releases_on_the_CDN_0">Microsoft CDN</a></p> <legend class="screen-reader-text"><span><?php _e('Choose your prefered cdn provider', $this->plugin_name);?></span></legend> <input type="url" class="regular-text" id="<?php echo $this->plugin_name;?>-cdn_provider" name="<?php echo $this->plugin_name;?>[cdn_provider]" value="<?php if(!empty($cdn_provider)) echo $cdn_provider;?>"/> </fieldset> </fieldset> <?php submit_button(__('Save all changes', $this->plugin_name), 'primary','submit', TRUE); ?> </form> </div> |
تنها تغییر GIF برای submit button() است. شما می توانید ببینید که اولین پارامتر (که button text است) داخلش متن __ () وجود دارد. این همانند _e () است بجز اینکه این متن به جای تکرار شدن، بازگردانده خواهد شد.
خب حالا، تمامی strings به افزونه مان مربوط هستند و poedit می تواند از آنها استفاده کند و آن را داخل its .pot file بصورت خودکار قرار دهد.
براوو! اکنون افزونه شما کاملا قابل ترجمه است.
انواع ورودی های پیچیده تر را اضافه کنید
ما پیش از این فایل های بسیاری به افزونه مان اضافه کرده ایم، اما فقط با دو نوع ورودی:
- Checkboxes
- Text inputs
حالا می خواهیم دو نوع ورودی متفاوت و پیچیده تر را اضافه کنیم.
- Color pickers
- File/Media uploads
برای انجام اینکار، بیایید یک قسمت جدید سفارشی ساختن صفحه ورود به افزونه مان در داخل فرم اضافه کنیم. ما قبلا بر روی فرم کار کرده ایم، این را بعد از html اضافه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/** * * admin/partials/wp-cbf-admin-display.php * **/ ... <form method="post" name="cleanup_options" action="options.php"> <?php //Grab all options $options = get_option($this->plugin_name); // Cleanup $cleanup = $options['cleanup']; $comments_css_cleanup = $options['comments_css_cleanup']; $gallery_css_cleanup = $options['gallery_css_cleanup']; $body_class_slug = $options['body_class_slug']; $jquery_cdn = $options['jquery_cdn']; $cdn_provider = $options['cdn_provider']; // New Login customization vars $login_logo_id = $options['login_logo_id']; $login_logo = wp_get_attachment_image_src( $login_logo_id, 'thumbnail' ); $login_logo_url = $login_logo[0]; $login_background_color = $options['login_background_color']; $login_button_primary_color = $options['login_button_primary_color']; ?> ... <!-- Login page customizations --> <h2 class="nav-tab-wrapper"><?php _e('Login customization', $this->plugin_name);?></h2> <p><?php _e('Add logo to login form change buttons and background color', $this->plugin_name);?></p> <!-- add your logo to login --> <fieldset> <legend class="screen-reader-text"><span><?php esc_attr_e('Login Logo', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-login_logo"> <input type="hidden" id="login_logo_id" name="<?php echo $this->plugin_name;?>[login_logo_id]" value="<?php echo $login_logo_id; ?>" /> <input id="upload_login_logo_button" type="button" class="button" value="<?php _e( 'Upload Logo', $this->plugin_name); ?>" /> <span><?php esc_attr_e('Login Logo', $this->plugin_name);?></span> </label> <div id="upload_logo_preview" class="wp_cbf-upload-preview <?php if(empty($login_logo_id)) echo 'hidden'?>"> <img src="<?php echo $login_logo_url; ?>" /> <button id="wp_cbf-delete_logo_button" class="wp_cbf-delete-image">X</button> </div> </fieldset> <!-- login background color--> <fieldset class="wp_cbf-admin-colors"> <legend class="screen-reader-text"><span><?php _e('Login Background Color', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-login_background_color"> <input type="text" class="<?php echo $this->plugin_name;?>-color-picker" id="<?php echo $this->plugin_name;?>-login_background_color" name="<?php echo $this->plugin_name;?>[login_background_color]" value="<?php echo $login_background_color;?>" /> <span><?php esc_attr_e('Login Background Color', $this->plugin_name);?></span> </label> </fieldset> <!-- login buttons and links primary color--> <fieldset class="wp_cbf-admin-colors"> <legend class="screen-reader-text"><span><?php _e('Login Button and Links Color', $this->plugin_name);?></span></legend> <label for="<?php echo $this->plugin_name;?>-login_button_primary_color"> <input type="text" class="<?php echo $this->plugin_name;?>-color-picker" id="<?php echo $this->plugin_name;?>-login_button_primary_color" name="<?php echo $this->plugin_name;?>[login_button_primary_color]" value="<?php echo $login_button_primary_color;?>" /> <span><?php esc_attr_e('Login Button and Links Color', $this->plugin_name);?></span> </label> </fieldset> <?php submit_button(__('Save all changes', $this->plugin_name), 'primary','submit', TRUE); ?> </form> |
حال متغیرهای جدید و همه ورودی های مورد نیازمان را اضافه کردیم. حالا باید یک متغیر به “cache” ارزش شان از متغیر $options اضافه کنیم. آنها اینجا هستند تا logo image url را همانطور که image id را در گزینه هایمان ذخیره می کنیم ، بگیرند.
1 2 |
$login_logo = wp_get_attachment_image_src( $login_logo_id, 'thumbnail' ); $login_logo_url = $login_logo[0]; |
هیچ چیز عجیبی نیست. به سادگی از wp_get_attachment_image_src استفاده می کنیم و از our login_logo_id
عبور می کنیم و این سایزی است که می خواهیم. سپس $login_logo_url به ما image url را می دهد، بنابراین می توانیم آنرا داخل ویژگی img src مان بکار ببریم.
به نتایج نگاه کنید، این چیزی نیست که ما انتظارش را داشتیم.
برای اینکه درست کار کند، باید JavaScript و CSS files در WordPress core اضافه کنیم تا آنرا نشان بدهد و درست کار کند.
admin/class-wp-cbf-admin.php را باز کنید و function عمومی enqueue_styles() و enqueue_scripts() را اضافه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/** * * admin/class-wp-cbf-admin.php * **/ public function enqueue_styles() { /** * This function is provided for demonstration purposes only. * * An instance of this class should be passed to the run() function * defined in Wp_Cbf_Loader as all of the hooks are defined * in that particular class. * * The Wp_Cbf_Loader will then create the relationship * between the defined hooks and the functions defined in this * class. */ if ( 'settings_page_wp-cbf' == get_current_screen() -> id ) { // CSS stylesheet for Color Picker wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wp-cbf-admin.css', array( 'wp-color-picker' ), $this->version, 'all' ); } } /** * Register the JavaScript for the admin area. * * @since 1.0.0 */ public function enqueue_scripts() { /** * This function is provided for demonstration purposes only. * * An instance of this class should be passed to the run() function * defined in Wp_Cbf_Loader as all of the hooks are defined * in that particular class. * * The Wp_Cbf_Loader will then create the relationship * between the defined hooks and the functions defined in this * class. */ if ( 'settings_page_wp-cbf' == get_current_screen() -> id ) { wp_enqueue_media(); wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-cbf-admin.js', array( 'jquery', 'wp-color-picker' ), $this->version, false ); } } |
همانطور که می بینید، ما به 2 stylesheets اضافه می کنیم: wp-picker-picker و thickbox. این موارد فقط درصورتی ضمیمه می شوند که ما به دلیل مشروط بودن در صورت وجود دستور در صفحه افزونه خود هستیم:
1 |
if ( 'settings_page_wp-cbf' == get_current_screen() -> id ) |
همانطور که دوباره مشاهده می کنید، هر دو تماس js و css ما وابستگی های قبلی اضافه شده را بارگیری می کنند. بنابراین هر کد که ما در آن ها اضافه خواهیم کرد، مقادیر پیش فرض را بازنویسی می کند:
1 2 3 |
wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wp-cbf-admin.css', array('wp-clor-picker' ), $this->version, 'all' ); wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-cbf-admin.js', array( 'jquery', 'wp-color-picker' ), $this->version, false ); |
اگر شما enqueue_scripts() function را می بینید، ممکن است برایتان عجیب باشد که چرا wp-color-picker, media-upload, یا thickbox scripts enqueued اینجا نیستند. خب Iris color-picker script فقط به عنوان یک وابسته ی javascript در افزونه ی ما بارگیری شده است.
در وردپرس از ورژن 3.5، Media Uploader دیگر از Thickbox استفاده نمی کند. برای بارگیری the new media uploader dependencies، فقط باید wp_enqueue_media() را اضافه کنیم و همه scripts های مورد نیاز بارگیری خواهند شد.
آن صفحات documentation برای اطلاعات بیشتر wp_enqueue_media() و wp.media the Javascript Reference را بررسی کنید.
و دوباره اگر در صفحه تنظیمات افزونه مان هستیم، فقط آن فایل ها را اضافه می کنیم.
1 |
wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-cbf-admin.js', array( 'jquery', 'wp-color-picker', 'media-upload' ), $this->version, false ); |
حالا بیایید چندتا javascript به JS file: admin/js/wp-cbf-admin.js افزونه مان اضافه کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
/** * * admin/js/wp-cbf-admin.js * **/ (function( $ ) { 'use strict'; /** * All of the code for your admin-specific JavaScript source * should reside in this file. * * Note that this assume you're going to use jQuery, so it prepares * the $ function reference to be used within the scope of this * function. * * From here, you're able to define handlers for when the DOM is * ready: * * $(function() { * * }); * * Or when the window is loaded: * * $( window ).load(function() { * * }); * * ...and so on. * * Remember that ideally, we should not attach any more than a single DOM-ready or window-load handler * for any particular page. Though other scripts in WordPress core, other plugins, and other themes may * be doing this, we should try to minimize doing that in our own work. */ $(function(){ // Let's set up some variables for the image upload and removing the image var frame, imgUploadButton = $( '#upload_login_logo_button' ), imgContainer = $( '#upload_logo_preview' ), imgIdInput = $( '#login_logo_id' ), imgPreview = $('#upload_logo_preview'), imgDelButton = $('#wp_cbf-delete_logo_button'), // Color Pickers Inputs colorPickerInputs = $( '.wp-cbf-color-picker' ); // WordPress specific plugins - color picker and image upload $( '.wp-cbf-color-picker' ).wpColorPicker(); // wp.media add Image imgUploadButton.on( 'click', function( event ){ event.preventDefault(); // If the media frame already exists, reopen it. if ( frame ) { frame.open(); return; } // Create a new media frame frame = wp.media({ title: 'Select or Upload Media for your Login Logo', button: { text: 'Use as my Login page Logo' }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected in the media frame... frame.on( 'select', function() { // Get media attachment details from the frame state var attachment = frame.state().get('selection').first().toJSON(); // Send the attachment URL to our custom image input field. imgPreview.find( 'img' ).attr( 'src', attachment.sizes.thumbnail.url ); // Send the attachment id to our hidden input imgIdInput.val( attachment.id ); // Unhide the remove image link imgPreview.removeClass( 'hidden' ); }); // Finally, open the modal on click frame.open(); }); // Erase image url and age preview imgDelButton.on('click', function(e){ e.preventDefault(); imgIdInput.val(''); imgPreview.find( 'img' ).attr( 'src', '' ); imgPreview.addClass('hidden'); }); }); // End of DOM Ready })( jQuery ); |
همان طور که در کامنت ها گفتیم، ما JS مان را داخل DOM ready function ضمیمه کردیم: $(function(){ …our code… }); که خودش در self-invoking anonymous function ضمیمه شده بود.
ابتدا چند vars را تعریف می کنیم که در Javascript مان استفاده خواهیم کرد، سپس برای color picker فقط wpColorPicker() را در color-picker fieldsفرا می خوانیم، واقعا چیز پیچیده ای نیست.
برای image uploadما اصولا از یک ورژن تطبیقی wp.media Javascript Reference استفاده می کنیم. بسیار در مورد آن اظهار نظر شده است، اما بیایید یکم آن را بررسی کنیم.
بطور واضح زمانی که بر روی ‘Upload Logo’ button کلیک می کنید، media upload frame را باز خواهیم کرد که برای آخرین عبارت imgUploadButton.on( ‘click’, function( event ){ … frame.open() }); تنظیم شده است.
این فریم نماینده wp. Media می باشد که برخی گزینه ها که در ادامه آمده است را در برمی گیرد:
- عنوان popup اینجا: عنوان: مدیا را برای لوگوی افزونه تان انتخاب یا آپلود کنید.
- متن آخرین دکمه سمت راست اینجا: دکمه:{متن: بعنوان لوگوی صفحه افزونه ام استفاده کن}
- یک گزینه ی انتخاب چندتایی(اگر میخواهید چند عکس را همزمان انتخاب کنید)، اینجا خطا در نظر گرفته می شود: multiple: false
سپس یک frame.on ( ‘select’, function() {}) داریم که هنگامی که ما یک uploaded image را انتخاب می کنیم فعال می شود و نتایج به عنوان JSON object نشان داده شده با attachment varرا در اینجا باز می گرداند.
1 2 3 |
var attachment = frame.state().get('selection').first().toJSON(); //console.log(attachment) |
شما می توانید این مورد را console.log کنید تا ببینید که لیستی از ویژگی های تصویرمان را به ما می دهد. ما آنرا بلافاصله بکار می بریم تا به img field مان src value بدهد (از attachment.sizes.thumbnail.url استفاده کنید تا یک تصویر 150x150px داشته باشید) و همچنین به hidden field ما image id بدهد.
1 |
<input type="hidden" id="login_logo_id" name="<?php echo $this->plugin_name;?>[login_logo_id]" value="<?php echo esc_url($login_logo_id); ?>` |
چرا بجای direct image url به آن id value می دهد؟ خب، با این روش سانسور کردن آسانتر می شود همانطور که فقط باید عدد باشد.
در نهایت، ما imgDelButton.on(‘click’, function(e){}); را داریم؛ که ارزش img source value را حذف می کند. اگر کلیک کنید file id value hidden و hidden class back را به preview controller اضافه می کند.
بنابراین با این JS کوچک، شما حالا یک تنظیمات کاملا کاربردی با برخی از بهترین ویژگی های ساخت وردپرس را دارید.
اکنون باید نتایجی همانند اسکرین شات زیر را مشاهده کنید که یک Iris color picker بسیار زیباست. اگر بر روی هر یک از color fields یا media uploader pop-up کلیک کنید، زمانی که بر روی Upload کلیک می کنید و هنگامی که عکس انتخاب می شود، لوگوی جدید ما به زیبایی آنجا نمایش داده خواهد شد.
کاملا درست و عالی!
اگر بار دیگر تمام آن ارزش های جدید را ذخیره کنید، هیچ اتفاقی نخواهد افتاد. برای ذخیره کردن و باز پس گیری ارزش های ورودی های جدیدمان، ما باید سانسور کردن و ذخیره کردن/ به روز رسانی را بررسی کنیم.
بیایید همین حالا این کار را انجام بدهیم
سانسور کردن و ذخیره کردن/ به روز رسانی فیلدهای پیچیده
همانطور که از بخش یک بخاطر دارید، register_setting( $this->plugin_name, $this->plugin_name, array($this, ‘validate’) ); ؛ حواستان به update/saving متغیرها و ارزش هایتان زمانی که از validate function تان ارزش گذاری شدند باشد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/** * * admin/class-wp-cbf-admin.php * **/ public function validate($input) { // All checkboxes inputs $valid = array(); //Cleanup $valid['cleanup'] = (isset($input['cleanup']) && !empty($input['cleanup'])) ? 1 : 0; $valid['comments_css_cleanup'] = (isset($input['comments_css_cleanup']) && !empty($input['comments_css_cleanup'])) ? 1: 0; $valid['gallery_css_cleanup'] = (isset($input['gallery_css_cleanup']) && !empty($input['gallery_css_cleanup'])) ? 1 : 0; $valid['body_class_slug'] = (isset($input['body_class_slug']) && !empty($input['body_class_slug'])) ? 1 : 0; $valid['jquery_cdn'] = (isset($input['jquery_cdn']) && !empty($input['jquery_cdn'])) ? 1 : 0; $valid['cdn_provider'] = esc_url($input['cdn_provider']); // Login Customization //First Color Picker $valid['login_background_color'] = (isset($input['login_background_color']) && !empty($input['login_background_color'])) ? sanitize_text_field($input['login_background_color']) : ''; if ( !empty($valid['login_background_color']) && !preg_match( '/^#[a-f0-9]{6}$/i', $valid['login_background_color'] ) ) { // if user insert a HEX color with # add_settings_error( 'login_background_color', // Setting title 'login_background_color_texterror', // Error ID 'Please enter a valid hex value color', // Error message 'error' // Type of message ); } //Second Color Picker $valid['login_button_primary_color'] = (isset($input['login_button_primary_color']) && !empty($input['login_button_primary_color'])) ? sanitize_text_field($input['login_button_primary_color']) : ''; if ( !empty($valid['login_button_primary_color']) && !preg_match( '/^#[a-f0-9]{6}$/i', $valid['login_button_primary_color'] ) ) { // if user insert a HEX color with # add_settings_error( 'login_button_primary_color', // Setting title 'login_button_primary_color_texterror', // Error ID 'Please enter a valid hex value color', // Error message 'error' // Type of message ); } //Logo image id $valid['login_logo_id'] = (isset($input['login_logo_id']) && !empty($input['login_logo_id'])) ? absint($input['login_logo_id']) : 0; return $valid; } |
اکنون validate function مان به این شکل خواهد بود- بیایید نگاهی به آن بیاندازیم.
برای login_logo_id چیزی برای گفتن نداریم. ما فقط چک می کنیم که $input[‘login_logo_id’] ثابت شده باشد و اگر نشده بود ما ارزش صفر به آن می دهیم (که وقتی با empty()). چک شده باشد false value است). اگر ثابت شده باشد، سپس مطمئن می شویم که این ارزش یک عدد صحیح کامل مثبت با absint است.
حال اجازه بدهید ارزشگذاری our Color pickerرا توضیح بدهیم، همانطور که با جزئیات دقیق تر می بینید.
ابتدا ارزش ورودی مان را وارد می کنیم و مطمئن می شویم که ثابت شده است و خالی نیست.
1 |
$valid['login_background_color'] = (isset($input['login_background_color']) && !empty($input['login_background_color'])) ? sanitize_text_field($input['login_background_color']) : ''; |
سپس اگر ارزش خالی نیست (یعنی یک ردیف خالی نیست)، ما آنرا در برابر یک regex آزمون می کنیم تا مطمئن شویم که یک hexadecimal string است. این به این معناست که باید با یک # شروع شود و سپس شامل 6 کاراکتر باشد که می تواند یک عدد صحیح بین 0 تا 9 یا یک حرف بین a-f باشد.
1 |
/^#[a-f0-9]{6}$/i |
اگر آزمون regex ناموفق باشد، چند settings error اضافه می کنیم که بخشی از settings_api است.
1 |
add_settings_error('login_button_primary_color', // Setting title 'login_button_primary_color_texterror', // Error ID 'Please enter a valid hex value color', // Error message 'error' // Type of message); |
همانطور که در add_settings_error documentation توضیح داده شد، اولین argument علامت مشخصی است که باید به تنظیمات ما مربوط باشد. در اینجا login_button_primary_color است.
سپس یک ردیفی با یک عنوان کوتاه دیگری داریم که به error message class اضافه خواهد شد: در اینجا، login_button_primary_color_texterror است.
سپس پیامی که می خواهید نشان داده شود (مهم است که نشان داده شود): لطفا یک hex value color معتبر وارد کنید.
و در نهایت پس ازینکه error را تایپ کردید که مانند ارزش پیش فرض خطاست اختیاری است.
در زیر اسکرین شات خطا آمده است وقتی که می خواهید یک non-hexadecimal stringبرای color picker ذخیره کنید.
اگر همه چیز درست است، اکنون به جای آن گزینه هایمان را با یک اعلان موفق ذخیره کرده ایم:
خب حالا یک دسته کامل از گزینه ها داریم با ارزش هایی که به درستی پاکسازی و ذخیره شده اند. اکنون وقت انست که به افزونه مان توانایی تغییر رفتار وب سایت مان را بدهیم.
Function هایی ایجاد کنید که رفتارtheme/backend ما را تغییر خواهد داد
هنوز افزونه و وب سایت وردپرس ما بر یکدیگر تاثیر متقابل ندارند. این همین الان تغییر می کند. ما آن را به 2 قسمت جدا تقسیم خواهیم کرد:
- قسمت “Clean up” وب سایت مان را درfront-end و login تغییر خواهد داد.
- و سپس “Login Customizations” در backend اعمال خواهد شد.
برای اینکه کدهایمان بخوبی برنامه ریزی شده نگهداری شوند، هر بخش را می توانید در پوشه مربوطه بنویسید. ما public را برای front-end و سپس admin را برای backend استفاده خواهیم کرد که کاملا کار معقولی هست.
توابع frontend ما
فایل public/class-wp-cbf-public.php را باز کنید و بعد از enqueue_scripts() تابع زیر را اضافه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
/** * * public/class-wp-cbf-public.php * **/ public function __construct( $plugin_name, $version ) { $this->plugin_name = $plugin_name; $this->version = $version; $this->wp_cbf_options = get_option($this->plugin_name); } /** * Cleanup functions depending on each checkbox returned value in admin * * @since 1.0.0 */ // Cleanup head public function wp_cbf_cleanup() { if($this->wp_cbf_options['cleanup']){ remove_action( 'wp_head', 'rsd_link' ); // RSD link remove_action( 'wp_head', 'feed_links_extra', 3 ); // Category feed link remove_action( 'wp_head', 'feed_links', 2 ); // Post and comment feed links remove_action( 'wp_head', 'index_rel_link' ); remove_action( 'wp_head', 'wlwmanifest_link' ); remove_action( 'wp_head', 'parent_post_rel_link', 10, 0 ); // Parent rel link remove_action( 'wp_head', 'start_post_rel_link', 10, 0 ); // Start post rel link remove_action( 'wp_head', 'rel_canonical', 10, 0 ); remove_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 ); remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 ); // Adjacent post rel link remove_action( 'wp_head', 'wp_generator' ); // WP Version remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); remove_action( 'wp_print_styles', 'print_emoji_styles' ); } } // Cleanup head public function wp_cbf_remove_x_pingback($headers) { if(!empty($this->wp_cbf_options['cleanup'])){ unset($headers['X-Pingback']); return $headers; } } // Remove Comment inline CSS public function wp_cbf_remove_comments_inline_styles() { if(!empty($this->wp_cbf_options['comments_css_cleanup'])){ global $wp_widget_factory; if ( has_filter( 'wp_head', 'wp_widget_recent_comments_style' ) ) { remove_filter( 'wp_head', 'wp_widget_recent_comments_style' ); } if ( isset($wp_widget_factory->widgets['WP_Widget_Recent_Comments']) ) { remove_action( 'wp_head', array($wp_widget_factory->widgets['WP_Widget_Recent_Comments'], 'recent_comments_style') ); } } } // Remove gallery inline CSS public function wp_cbf_remove_gallery_styles($css) { if(!empty($this->wp_cbf_options['gallery_css_cleanup'])){ return preg_replace( "!<style type='text/css'>(.*?)</style>!s", '', $css ); } } // Add post/page slug public function wp_cbf_body_class_slug( $classes ) { if(!empty($this->wp_cbf_options['body_class_slug'])){ global $post; if(is_singular()){ $classes[] = $post->post_name; } } return $classes; } // Load jQuery from CDN if available public function wp_cbf_cdn_jquery(){ if(!empty($this->wp_cbf_options['jquery_cdn'])){ if(!is_admin()){ if(!empty($this->wp_cbf_options['cdn_provider'])){ $link = $this->wp_cbf_options['cdn_provider']; }else{ $link = 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'; } $try_url = @fopen($link,'r'); if( $try_url !== false ) { wp_deregister_script( 'jquery' ); wp_register_script('jquery', $link, array(), null, false); } } } } |
اولین چیز اینست که ما رفرنسی به گزینه های ذخیره شده مان اضافه کردیم:
1 |
$this->wp_cbf_options = get_option($this->plugin_name); |
بنابراین ما می توانیم آنرا به functions مان اضافه کنیم.
می خواهیم چندpublic functions اضافه کنیم که هر کدام شامل شرطی است که بررسی می کند گزینه مربوطه بررسی شده است یا نه (در اینجا رفرنس بسیار مفید $this->wp_cbf_options را داریم)
اجازه بدیدfunction wp_cbf_bobody_class_slug را به عنوان مثال بیاوریم، body_class documentation on the WordPress Codex را ببینید و بیایید پایین صفحه تا برسید به “Add Classes By Filters” و این مثال را ببینید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* From the WordPress Codex */ // Add specific CSS class by filter add_filter( 'body_class', 'my_class_names' ); function my_class_names( $classes ) { // add 'class-name' to the $classes array $classes[] = 'class-name'; // return the $classes array return $classes; } /* From our Plugin */ public function wp_cbf_body_class_slug( $classes ) { if(!empty($this->wp_cbf_options['body_class_slug'])){ global $post; if(is_singular()){ $classes[] = $post->post_name; } } return $classes; } |
همانطور که می خواهیم post_nameرا اضافه کنیم اگر که در یک صفحه هستیم، یک صفحه پیوست یا یک پست تکی is_singular، می توانیم ببینیم که داریم از همان فرمت با تغییراتی در افزونه مان استفاده می کنیم. سپس می توانیم به $classes array augmented with our new class برگردیم.
ممکن است در مثال ما به این نکته توجه کنید که ما add_filter را به عنوان مثال Codex’ نیاورده ایم. این بخاطر اینست که ما می خواهیم همه front-end های مربوط به filters و actions هایمان را به function خصوصی define_public_hooks اضافه کنیم و backend های مربوط به filters و actions هایمان را به define_admin_hooks اضافه کنیم. اگر به یاد داشته باشید، این functions در فولدر includes در class-wp-cbf.php file هستند.
بیایید این کار را انجام بدهیم و actions and filters را به includes/class-wpcbf.php اضافه کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/** * * includes/class-wp-cbf.php * **/ /** * Register all of the hooks related to the public-facing functionality * of the plugin. * * @since 1.0.0 * @access private */ private function define_public_hooks() { $plugin_public = new Wp_Cbf_Public( $this->get_plugin_name(), $this->get_version() ); /* * The following actions are commented out as we won't need any added style or script to our theme $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' ); $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' ); */ // Below are our "public" frontend related actions and filters hooks // Cleanup - Actions and filters //Actions $this->loader->add_action( 'init', $plugin_public, 'wp_cbf_cleanup' ); $this->loader->add_action( 'wp_loaded', $plugin_public, 'wp_cbf_remove_comments_inline_styles' ); $this->loader->add_action( 'wp_loaded', $plugin_public, 'wp_cbf_remove_gallery_styles' ); $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'wp_cbf_cdn_jquery', PHP_INT_MAX); //Filters $this->loader->add_filter('wp_headers', $plugin_public, 'wp_cbf_remove_x_pingback'); $this->loader->add_filter( 'body_class', $plugin_public, 'wp_cbf_body_class_slug' ); } |
اول خواهید دید که برای enqueue_styles, enqueue_scripts actionsکامنت گذاشته ام. این به این خاطر است که این افزونه هیچ کدام از CSS یا Javascript را به وب سایت ما اضافه نخواهد کرد. اگر نیاز دارید تا style یا interaction به وب سایت تان با افزونه تان به front-end اضافه کنید، باید چندتا کد به این فایل ها(public/css/wp-cbf-public.css, public/js/wp-cbf-public.js) اضافه کنید. همچنین برای آن دوتا actions کامنت نگذاشته ایم.
4 actions و 2 تا filters مربوط به 6 تا از functionsهایمان اضافه کرده ایم. اجازه بدید یکی از hook calls ها را توضیح بدهیم. ما همان body_class slug مان را به عنوان مثال می آوریم.
1 |
$this->loader->add_filter( 'body_class', $plugin_public, 'wp_cbf_body_class_slug' ); |
با نگاهی به add_filter function (که ما آنرا $this->loader->add_filter می نامیم) از includes/class-wp-cbf-loader.php، آنچه در ادامه امده است را داریم:
1 2 3 4 |
public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); } |
بنابراین به سادگی می توانیم از آن سر در بیاوریم:
-
- $hook ا،’body_class’ است
- $component ، $plugin_public تعریف شده است. در ابتدای define_public_hook، ما از آن برای همه “public”(frontend) hooks calls هایمان استفاده خواهیم کرد.
- $callback در اینجا function ما wp_cbf_body_class_slug را class-wp-cbf-public.php می نامد.
- $priority با ارزش پیش فرض 10، نیازی نیست تا از این call مشخص کنیم اما باید hookتان الویت بالاتری داشته باشد، درنتیجه فقط باید عدد صحیح به آن اضافه کنید.
- $accepted_args با ارزش پیش فرض 1، همانند اینجا ما یک آرایه را گذرانده ایم بنابراین نباید آنرا مشخص کنیم، اما بسته به hook که می خواهید فراخوانید باید آنرا طبق documentation تنظیم کنید.
البته بسته به به چیزی که می خواهید تغییر بدهید، باید documentation را جستجو کنید تا بفهمید کدام action/filter ، در مقابل کدام hook ، همگی با کدام آرایه و الویت باید انتخاب شوند.
خب، ببینیم نتایج چه شد:
برمیگردیم به admin وب سایت مان و اولین uncheck ‘Add Post slug to body class . اگر بررسی شده است ذخیره کنید و به هر صفحه یا پست تکی که می خواهید بروید. من می خواهم به صفحه نمونه پیش فرض از نصب وردپرس اولیه بروم و page body class از developer tools بررسی کنم. این چیزی است که باید داشته باشید (کمتر یا بیشتر بسته به افزونه ای که قبلا نصب و فعال کرده اید):
حالا باید "Add Post slug to body class" را فعال کنید و سپس نتایجی مانند اسکرین شات زیر را داشته باشید. حالا post/page slug به body class اضافه می شود:
احسنت! افزونه ما front-end ما را همانگونه که می خواستیم تغییر داد. حالا باید checkbox را چک کنیم و یا می توانیم چک نکنیم، می توانیم این کار را برای هر وب سایتی که می خواهیم انجام بدهیم.
البته که می توانید چک کنید و باید چیزهایی که اتفاق می افتند را با گزینه های دیگرتان چک کنید. حالا وقت این است که backend functions مان را اضافه کنیم.
Backend functions
admin/class-wp-cbf-admin.php را باز کنید و بعد از validate() function مانند زیر این ها را اضافه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
/** * * admin/class-wp-cbf-admin.php * **/ ... public function __construct( $plugin_name, $version ) { $this->plugin_name = $plugin_name; $this->version = $version; $this->wp_cbf_options = get_option($this->plugin_name); } ... /** * Login page customizations Functions * * @since 1.0.0 */ private function wp_cbf_login_logo_css(){ if(isset($this->wp_cbf_options['login_logo_id']) && !empty($this->wp_cbf_options['login_logo_id'])){ $login_logo = wp_get_attachment_image_src($this->wp_cbf_options['login_logo_id'], 'thumbnail'); $login_logo_url = $login_logo[0]; $login_logo_css = "body.login h1 a {background-image: url(".$login_logo_url."); width:253px; height:102px; background-size: contain;}"; return $login_logo_css; } } // Get Background color is set and different from #fff return it's css private function wp_cbf_login_background_color(){ if(isset($this->wp_cbf_options['login_background_color']) && !empty($this->wp_cbf_options['login_background_color']) ){ $background_color_css = "body.login{ background:".$this->wp_cbf_options['login_background_color']."!important;}"; return $background_color_css; } } // Get Button and links color is set and different from #00A0D2 return it's css private function wp_cbf_login_button_color(){ if(isset($this->wp_cbf_options['login_button_primary_color']) && !empty($this->wp_cbf_options['login_button_primary_color']) ){ $button_color = $this->wp_cbf_options['login_button_primary_color']; $border_color = $this->sass_darken($button_color, 10); $message_color = $this->sass_lighten($button_color, 10); $button_color_css = "body.login #nav a, body.login #backtoblog a { color: ".$button_color." !important; } .login .message { border-left: 4px solid ".$message_color."; } body.login #nav a:hover, body.login #backtoblog a:hover { color: ". $border_color." !important; } body.login .button-primary { background: ".$button_color."; /* Old browsers */ background: -moz-linear-gradient(top, ".$button_color." 0%, ". $border_color.", 10%) 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,".$button_color."), color-stop(100%, ". $border_color.", 10%))); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, ".$button_color." 0%, ". $border_color.", 10%) 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, ".$button_color." 0%, ". $border_color.", 10%) 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, ".$button_color." 0%, ". $border_color.", 10%) 100%); /* IE10+ */ background: linear-gradient(to bottom, ".$button_color." 0%, ". $border_color.", 10%) 100%); /* W3C */ -webkit-box-shadow: none!important; box-shadow: none !important; border-color:". $border_color."!important; } body.login .button-primary:hover, body.login .button-primary:active { background: ". $border_color."; /* Old browsers */ background: -moz-linear-gradient(top, ". $border_color." 0%, ". $border_color.", 10%) 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,". $border_color."), color-stop(100%,". $border_color.", 10%))); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, ". $border_color." 0%,". $border_color.", 10%) 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, ". $border_color." 0%,". $border_color.", 10%) 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, ". $border_color." 0%,". $border_color.", 10%) 100%); /* IE10+ */ background: linear-gradient(to bottom, ". $border_color." 0%,". $border_color.", 10%) 100%); /* W3C */ } body.login input[type=checkbox]:checked:before{ color:".$button_color."!important; } body.login input[type=checkbox]:focus, body.login input[type=email]:focus, body.login input[type=number]:focus, body.login input[type=password]:focus, body.login input[type=radio]:focus, body.login input[type=search]:focus, body.login input[type=tel]:focus, body.login input[type=text]:focus, body.login input[type=url]:focus, body.login select:focus, body.login textarea:focus { border-color: ".$button_color."!important; -webkit-box-shadow: 0 0 2px ".$button_color."!important; box-shadow: 0 0 2px ".$button_color."!important; }"; return $button_color_css; } } // Write the actually needed css for login customizations public function wp_cbf_login_css(){ if( !empty($this->wp_cbf_options['login_logo_id']) || $this->wp_cbf_login_background_color() != null || $this->wp_cbf_login_button_color() != null){ echo '<style>'; if( !empty($this->wp_cbf_options['login_logo_id'])){ echo $this->wp_cbf_login_logo_css(); } if($this->wp_cbf_login_background_color() != null){ echo $this->wp_cbf_login_background_color(); } if($this->wp_cbf_login_button_color() != null){ echo $this->wp_cbf_login_button_color(); } echo '</style>'; } } /** * Utility functions * * @since 1.0.0 */ private function sass_darken($hex, $percent) { preg_match('/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $hex, $primary_colors); str_replace('%', '', $percent); $color = "#"; for($i = 1; $i <= 3; $i++) { $primary_colors[$i] = hexdec($primary_colors[$i]); $primary_colors[$i] = round($primary_colors[$i] * (100-($percent*2))/100); $color .= str_pad(dechex($primary_colors[$i]), 2, '0', STR_PAD_LEFT); } return $color; } private function sass_lighten($hex, $percent) { preg_match('/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $hex, $primary_colors); str_replace('%', '', $percent); $color = "#"; for($i = 1; $i <= 3; $i++) { $primary_colors[$i] = hexdec($primary_colors[$i]); $primary_colors[$i] = round($primary_colors[$i] * (100+($percent*2))/100); $color .= str_pad(dechex($primary_colors[$i]), 2, '0', STR_PAD_LEFT); } return $color; } |
همانطور که می بینید اینجا کمی متفاوت است ولی هیچ ربطی به این ندارد که ما admin related functions را اضافه می کنیم. این بخاطر اینست که چطور این functions های خاص استفاده خواهند شد. بنابراین مثال خوبی هم هست. با این حال چیزی که تغییر نمی کند اینست که ما باید رفرنسی به گزینه های افزونه مان در __construct function اضافه کنیم:
$this->wp_cbf_options = get_option($this->plugin_name);
سپس اینجا سه تابع خصوصی داریم که a chunk of CSS code را باز می گرداند:
- $login_logo_css توسط تابع خصوصی wp_cbf_login_logo_css() باز می گردانده می شود.
- $background_color_css توسط تابع خصوصی wp_cbf_login_background_color() بازمی گردانده می شود.
- و CSS کمی طولانی تر توسط تابع خصوصی wp_cbf_login_button_color() بعنوان $button_color_css بازگردانده می شود.
در زیر آن سه تابع خصوصی تابعی داریم که بعنوان callback در hook definition نامیده خواهد شد.
ممکن است برایتان این سوال بوجود بیاید که آن دو تابع خصوصی چه هستند. آنهاhelpers to emulate sass darken و lighten HSL functions هستند. بنابراین می توانیم دسته ای از رنگ های نسبتا متفاوت برای hover یا active state در button یا link بکار ببریم.
پس اساسا اینجا تابعی داریم که a <style>...our CSS code...</style> tag را توسط سه تابع خصوصی اول به صفحه افزونه ما با CSS code بازگردانده است.
بیایید hooks را به includes/class-wp-cbf.php داخل define_admin_hooks() function ، اضافه کنیم.
1 2 3 4 5 6 7 8 |
/** * * includes/class-wp-cbf.php * **/ //Admin Customizations $this->loader->add_action( 'login_enqueue_scripts', $plugin_admin, 'wp_cbf_login_css' ); |
و این یک خطی است. اینجا دقیقا همان عبارت $this->loader->add_action را استفاده می کنیم، تنها تغییر در $component است و اینجا بجای $plugin_public ، $plugin_admin را فرا می خوانیم
بیایید آنرا امتحان کنیم. هنگامی که شما logo image را اضافه کردید و یک رنگ برای بک گراند افزونه تان و primary button و link color انتخاب کردید و ذخیره شد، خارج شوید و دوباره به صفحه ورود بروید، می بینید که رنگ های لوگو، بک گراند و دکمه ها و لینک ها طبق آنچه که در صفحه تنظیمات افزونه تان انتخاب کردید تغییر کرده است.
براوو! حالا یک افزونه کاملا کاربردی دارید. شما می توانید از آن برای همه وب سایت ها استفاده کنید فقط کافیست آن را آپلود کنید و تنظیمات آنرا کانفیگ کنید.
تست افزونه مان
خب حالا از افزونه مان راضی هستیم و باید همه کارایی های آن را تست کنیم، اما اگر می خواهید بیشتر بررسی کنید پیشنهاد می کنم Developer Plugin را در حالی که در حال توسعه است به افزونه تان اضافه کنید، به شما تمامی ابزارهای مورد نیاز برای تست افزونه تان a PHP/MYSQL console و خیلی چیزهای دیگر را می دهد.
یک مرحله ی جالب دیگر BDD و Behavior Driven Development است، این موارد موضوع این آموزش نیستد، اما ممکن است موضوعی جالب باشند برای اینکه بعدا بدان پرداخته شود، اگر می خواهید خودتان آنرا مطالعه کنید، حتما نگاهی به Codeception بیندازید.
به هر حال هنگامی که مطمئن شدید افزونه تان به درستی کار می کند، بدون هیچ Errors یا Notice، می توانید آنرا برای تیم وردپرس بفرستید تا آنرا بررسی کنند.
ارسال افزونه مان برای بررسی توسط تیم وردپرس
خب شما تمامی این کار را انجام دادید و می خواهید آنرا با همه دنیا به اشتراک بگذارید، این بسیار عالی است اما افزونه شما باید توسط ورد پرس بررسی شود قبل از اینکه به منبع افزونه وردپرس راه پیدا کند.
قبل از اینکه آنرا ارسال کنید، و یا آنرا Archive(.zip) کنید و برای به اشتراک گذاری آماده کنید (برای مثال بر روی Dropbox یا Google Drive )، چگونه افزونه تان را برای بررسی ارسال کنید how to send your plugin for review را مطالعه کنید.
اگر تا به حال اکانتی درست نکرده اید می توانید در WordPress.orgاکانتی ایجاد کنید.
پس از ارائه ی افزونه فقط باید صبر کنید، چرا که افراد تیم وردپرس افزونه های بسیاری برای بررسی دارند.
هنگامیکه تایید شد، باید افزونه تان را برای [WordPress SVN repository][29] ارسال کنید، اما قبل از آن مطمئن شوید که فایل readme.txt معتبر است.
نتیجه گیری
خب این از این! ما به لطف WordPress plugin boilerplate یک از افزونه وردپرس کاملا کاربردی از scratch ساختیم. ما مطالبی بسیاری را پوشش دادیم، از اینکه چطور افزونه بسازیم و از کجا شروع کنیم تا خود برنامه نویسی افزونه و اینکه چگونه آنرا سازماندهی و پاکسازی کنیم.
امیدوارم که برای شما دوستان مفید بوده باشد و همانقدر که من از پرداختن به این موضوع لذت بردن، شما هم لذت برده باشید.
درآینده می توانیم مطلب کوتاهی هم در مورد styling صفحه تنظیمات افزونه و یا همچنین اضافه کردن interaction با کمی Javascript به عنوان adding tabs برای مثال داشته باشیم. اما اول دوست دارم که نظر شما عزیزان را در مورد آن بدانم.
و البته برای یادگیری بیشتر در مورد افزونه های وردپرس به WordPress Plugin Guideline. مراجعه کنید.
خسته نباشید!
درباره بهروز قاسمی
عاشق راه اندازی کسب و کارهای اینترنتی... مدرس و مشاور دیجیتال مارکتینگ/ موسس وب سایت مدیران وردپرس/ مدیر واحد دیجیتال مارکتینگ شرکت آوب
نوشته های بیشتر از بهروز قاسمی1 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
😍 خیلی خوشحالم!
لطفا برای اینکه به ما انگیزه و انرژی بیشتری بدی، از طریق فرم زیر برای ما نظرت رو ارسال کن. 😍
😟 شرمنده ام!
خیلی ناراحت شدم که این مطلب برای شما کاربردی نبود 🙁 به کمکت نیاز دارم تا این محتوا رو بهتر کنم. لطفا پیشنهادت رو برام از طریق فرم زیر ارسال کن تا کیفیت این محتوا رو بیشتر کنم. 🙏
لغو پاسخ
لطفا برای اینکه به ما انگیزه و انرژی بیشتری بدی، از طریق فرم زیر برای ما نظرت رو ارسال کن. 😍
خیلی ناراحت شدم که این مطلب برای شما کاربردی نبود 🙁 به کمکت نیاز دارم تا این محتوا رو بهتر کنم. لطفا پیشنهادت رو برام از طریق فرم زیر ارسال کن تا کیفیت این محتوا رو بیشتر کنم. 🙏
خیلی مطلب خوب بود. تشکر از شما