Wednesday, September 21, 2016

The 10 Most Common Mistakes That WordPress Developers Make

We are only human, and one of the traits of being a human is that we make mistakes. On the other hand, we are also self-correcting, meaning we tend to learn from our mistakes and hopefully are thereby able to avoid making the same ones twice. A lot of the mistakes I have made in the WordPress realm originate from trying to save time when implementing solutions. However, these would typically rear their heads down the road when issues would crop up as a result of this approach. Making mistakes is inevitable. However, learning from other people’s oversights (and your own of course!) is a road you should proactively take.
WordPressEngineers look like superheroes, but we’re still human. Learn from us.

Common Mistake #1: Keeping the Debugging Off

Why should I use debugging when my code is working fine? Debugging is a feature built into WordPress that will cause all PHP errors, warnings, and notices (about deprecated functions, etc.) to be displayed. When debugging is turned off, there may be important warnings or notices being generated that we never see, but which might cause issues later if we don’t deal with them in time. We want our code to play nicely with all the other elements of our site. So, when adding any new custom code to WordPress, you should always do your development work with debugging turned on (but make sure to turn it off before deploying the site to production!).
To enable this feature, you’ll need to edit the wp-config.php file in the root directory of your WordPress install. Here is a snippet of a typical file:
// Enable debugging
define('WP_DEBUG', true);

// Log all errors to a text file located at /wp-content/debug.log
define('WP_DEBUG_LOG', true);

// Don’t display error messages write them to the log file /wp-content/debug.log
define('WP_DEBUG_DISPLAY', false);

// Ensure all PHP errors are written to the log file and not displayed on screen
@ini_set('display_errors', 0);
This is not an exhaustive list of configuration options that can be used, but this suggested setup should be sufficient for most debugging needs.

Common Mistake #2: Adding Scripts and Styles Using wp_head Hook

What is wrong with adding the scripts into my header template? WordPress already includes a plethora of popular scripts. Still, many developers will add additional scripts using the wp_head hook. This can result in the same script, but a different version, being loaded multiple times.
Enqueuing here comes to the rescue, which is the WordPress friendly way of adding scripts and styles to our website. We use enqueuing to prevent plugin conflicts and handle any dependencies a script might have. This is achieved by using the inbuilt functions wp_enqueue_script or wp_enqueue_style to enqueue scripts and styles respectively. The main difference between the two functions is that with wp_enqueue_script we have an additional parameter that allows us to move the script into the footer of the page.
wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false )
wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false )

wp_register_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' )
wp_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' )
If the script is not required to render content above the fold, we can safely move it to the footer to make sure the content above the fold loads quickly. It’s good practice to register the script first before enqueuing it, as this allows others to deregister your script via the handle in their own plugins, without modifying the core code of your plugin. In addition to this, if the handle of a registered script is listed in the array of dependencies of another script that has been enqueued, that script will automatically be loaded prior to loading that highlighted enqueued script.

Common Mistake #3: Avoiding Child Themes and Modifying WordPress Core Files

Always create a child theme if you plan on modifying a theme. Some developers will make changes to the parent theme files only to discover after an upgrade to the theme that their changes have been overwritten and lost forever.
To create a child theme, place a style.css file in a subdirectory of the child theme’s folder, with the following content:
/*
 Theme Name:   Twenty Sixteen Child
 Theme URI:    http://example.com/twenty-fifteen-child/
 Description:  Twenty Fifteen Child Theme
 Author:       John Doe
 Author URI:   http://example.com
 Template:     twentysixteen
 Version:      1.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twenty-sixteen-child
*/
The above example creates a child theme based on the default WordPress theme, Twenty Sixteen. The most important line of this code is the one containing the word “Template” which must match the directory name of the parent theme you are cloning the child from.
The same principles apply to WordPress core files: Don’t take the easy route by modifying the core files. Put in that extra bit of effort by employing WordPress pluggable functions and filters to prevent your changes from being overwritten after a WordPress upgrade. Pluggable functions let you override some core functions, but this method is slowly being phased out and replaced with filters. Filters achieve the same end result and are inserted at the end of WordPress functions to allow their output to be modified. A trick is always to wrap your functions with if ( !function_exists() ) when using pluggable functions since multiple plugins trying to override the same pluggable function without this wrapper will produce a fatal error.

Common Mistake #4: Hardcoding Values

Often it looks quicker to just hardcode a value (such as a URL) somewhere in the code, but the time spent down the road debugging and rectifying issues that arise as a result of this is far greater. By using the corresponding function to generate the desired output dynamically, we greatly simplify subsequent maintenance and debugging of our code. For example, if you migrate your site from a test environment to production with hardcoded URLs, all of a sudden you’ll notice your site it is not working. This is why we should employ functions, like the one listed below, for generating file paths and links:
// Get child theme directory uri
stylesheet_directory_uri();
//  Get parent theme directory
get_template_directory_uri();
// Retrieves url for the current site
 site_url();
Another bad example of hardcoding is when writing custom queries. For example, as a security measure, we change the default WordPress datatable prefix from wp_ to something a little more unique, like wp743_. Our queries will fail if we ever move the WordPress install, as the table prefixes can change between environments. To prevent this from happening, we can reference the table properties of the wpdb class:
global $wpdb;
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
Notice how I am not using the value wp_users for the table name, but instead, I’m letting WordPress work it out. Using these properties for generating the table names will help ensure that we return the correct results.

Common Mistake #5: Not Stopping Your Site From Being Indexed

Why wouldn’t I want search engines to index my site? Indexing is good, right? Well, when building a website, you don’t want search engines to index your site until you have finished building it and have established a permalink structure. Furthermore, if you have a staging server where you test site upgrades, you don’t want search engines like Google indexing these duplicate pages. When there are multiple pieces of indistinguishable content, it is difficult for search engines to decide which version is more relevant to a search query. Search engines will in such cases penalize sites with duplicate content, and your site will suffer in search rankings as a result of this.
As shown below, WordPress Reading Settings has a checkbox that reads “Discourage search engines from indexing this site”, although this does have an important-to-note underneath stating that “It is up to search engines to honor this request”.
WordPress Reading Settings
Bear in mind that search engines often do not honor this request. Therefore, if you want to reliably prevent search engines from indexing your site, edit your .htaccess file and insert the following line:
Header set X-Robots-Tag "noindex, nofollow"

Common Mistake #6: Not Checking if a Plugin is Active

Why should I check if a plugin function exists if my plugin is always switched on? For sure, 99% of the time your plugin will be active. However, what about that 1% of the time when for some reason it has been deactivated? If and when this occurs, your website will probably display some ugly PHP errors. To prevent this, we can check to see if the plugin is active before we call its functions. If the plugin function is being called via the front-end, we need to include the plugin.php library in order to call the function is_plugin_active():
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if ( is_plugin_active( 'plugin-folder/plugin-main-file.php' ) ) {
// Run plugin code
}
This technique is usually quite reliable. However, there could be instances where the author has changed the main plugin directory name. A more robust method would be to check for the existence of a class in the plugin:
if( class_exists( ‘WooCommerce’ ) ) {
 // The plugin WooCommerce is turned on
}
Authors are less likely to change the name of a plugin’s class, so I would generally recommend using this method.

Common Mistake #7: Loading Too Many Resources

Why should we be selective in loading plugin resources for pages? There is no valid reason to load styles and scripts for a plugin if that plugin is not used on the page that the user has navigated to. By only loading plugin files when necessary, we can reduce our page loading time, which will result in an improved end user experience. Take, for example, a WooCommerce site, where we only want the plugin to be loaded on our shopping pages. In such a case, we can selectively remove any files from being loaded on all the other sites pages to reduce bloating. We can add the following code to the theme or plugin’s functions.php file:
function load_woo_scripts_styles(){
 
if( function_exists( 'is_woocommerce' ) ){
    // Only load styles/scripts on Woocommerce pages   
 if(! is_woocommerce() && ! is_cart() && ! is_checkout() ) {   
  
  // Dequeue scripts.
  wp_dequeue_script('woocommerce'); 
  wp_dequeue_script('wc-add-to-cart'); 
  wp_dequeue_script('wc-cart-fragments');
  
  // Dequeue styles. 
  wp_dequeue_style('woocommerce-general'); 
  wp_dequeue_style('woocommerce-layout'); 
  wp_dequeue_style('woocommerce-smallscreen'); 
   
  }
 } 
}

add_action( 'wp_enqueue_scripts', 'load_woo_scripts_styles');
Scripts can be removed with the function wp_dequeue_script($handle) via the handle with which they were registered. Similarly, wp_dequeue_style($handle) will prevent stylesheets from being loaded. However, if this is too challenging for you to implement, you can install the Plugin Organizer that provides the ability to load plugins selectively based on certain criteria, such as a post type or page name. It’s a good idea to disable any caching plugins, like W3Cache, that you may have switched on to stop you from having to refresh the cache constantly to reflect any changes you have made.

Common Mistake #8: Keeping the Admin Bar

Can’t I just leave the WordPress Admin Bar visible for everyone? Well, yes, you could allow your users access to the admin pages. However, these pages very often do not visually integrate with your chosen theme and don’t provide a seamless integration. If you want your site to look professional, you should disable the Admin Bar and provide a front-end account management page of your own:
add_action('after_setup_theme', 'remove_admin_bar');

function remove_admin_bar() {
if (!current_user_can('administrator') && !is_admin()) {
  show_admin_bar(false);
}
}
The above code, when copied into your theme’s functions.php file will only display the Admin Bar for administrators of the site. You can add any of the WordPress user roles or capabilities into the current_user_can($capability) function to exclude users from seeing the admin bar.

Common Mistake #9: Not Utilizing the GetText Filter

I can use CSS or JavaScript to change the label of a button, what’s wrong with that? Well, yes, you can. However, you’re adding superfluous code and extra time to render the button, when you can instead use one of the handiest filters in WordPress, called gettext. In conjunction with a plugin’s textdomain, a unique identifier that ensures WordPress can distinguish between all loaded translations, we can employ the gettextfilter to modify the text before the page is rendered. If you search the source code for the function load_plugin_textdomain($domain), it will give you the domain name we need to override the text in question. Any reputable plugin will ensure that the textdomain for a plugin is set on initialization of the plugin. If it’s some text in a theme that you want to change, search for the load_theme_textdomain($domain) line of code. Using WooCommerce once again as an example, we can change the text that appears for the “Related Products” heading. Insert the following code into your theme’s functions.php file:
function translate_string( $translated_text, $untranslated_text, $domain ) {
 if ( $translated_text == 'Related Products') {
   $translated_text = __( 'Other Great Products', 'woocommerce' );
 }
 return $translated_text;
}

add_filter( 'gettext', 'translate_string', 15, 3 );
This filter hook is applied to the translated text by the internationalization functions __() and _e(), as long as the textdomain is set via the aforementioned functions.
_e( 'Related Products', 'woocommerce' );
Search your plugins for these internationalization functions to see what other strings you can customize.
By default, WordPress uses a query string with the post’s ID to return the specified content. However, this is not user-friendly and users may remove pertinent parts of the URL when copying it. More importantly, these default permalinks do not use a search engine friendly structure. Enabling what we call “pretty” permalinks will ensure our URLs contain relevant keywords from the post title to improve performance in search engine rankings. It can be quite a daunting task having to retrospectively modify your permalinks, especially if your site has been running for a significant period of time, and you’ve got hundreds of posts already indexed by search engines. So after you’ve installed WordPress, ensure you promptly change your permalinks structure to something a little more search engine friendly than just a post ID. I generally use the post name for the majority of sites I build, but you can customize the permalink to whatever format you like using the availablepermalink structure tags.
WordPress Permalink Settings

Conclusion

This article is by no means an exhaustive list of mistakes made by WordPress developers. If there’s one thing you should take away from this article, though, it’s that you should never take shortcuts (and that’s true in any development platform, not just in WordPress!). Time saved now by poor programming practices will come back to haunt you later. Feel free to share with us some mistakes that you have made in the past – and more importantly any lessons learned – by leaving a comment below.
This article was written by Andrew Schultz, a Toptal freelance developer.

56 comments:

thendral said...

Nicz.I need some tips related to your content..I am working in Cloud Erp In India

smrithi said...

Thanks for sharing this Informative content. Well explained. Got to learn new things from your Blog on SAP SD.SAP SD

Webtrackker Noida said...

Webtrackker technology is the best IT training institute in NCR. Webtrackker provide training on all latest technology such as Sap Basis training. Webtrackker is not only training institute but also it also provide best IT solution to his client. Webtrackker provide training by experienced and working in the industry on same technology.Webtrackker Technology C-67 Sector-63 Noida 8802820025

SAP basis Training institute in indirapuram


SAP basis Training institute in Noida


SAP basis Training institute in Ghaziabad


SAP basis Training institute in Vasundhara


SAP basis Training institute in Vaishali


SAP basis Training institute in Delhi South Ex

Sindhuja Ravi said...

Finding the time and actual effort to create a superb article like this is great thing. I’ll learn many new stuff right here! Good luck for the next post buddy..
Digital Marketing Company in Chennai

camelliacanan said...

A nice article here with some useful tips for those who are not used-to comment that frequently. Thanks for this helpful information I agree with all points you have given to us. I will follow all of them.
SAP HANA Training in Chennai
SAP MM Training in chennai
SAP Basis Training in chennai

iWEB TECHNOLOGIES said...

Appreciative for such brilliant blog yours...!
Wordpress Development Company in India

Philips Huges said...


Nice Sharing..! I have been following you for a couple of months now but this is my first time commenting on a blog post. Thank you for sharing your knowledge and experience with us. Keep up the good work. Already bookmarked for future reference.

Installment loans in Mississippi
Payday loans in Mississippi
Title loans in Mississippi

Priya Kannan said...

Great post! I am see the programming coding and step by step execute the outputs.I am gather this coding more information. It's helpful for me my friend. Also great blog here with all of the valuable information you have.
PHP Training in Chennai

sunitha vishnu said...

Really it was an awesome article...very interesting to read..You have provided an nice article....Thanks for sharing..
Android Training in Chennai
Ios Training in Chennai

Nemco said...

Great post! I am actually getting ready to across this information, It's very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
WordPress theme development | ios app development

Srinu Vasu said...

Nice Article. The SAP Basis Online Training was Really help ful for me. Keep Sharing…………

Ancy merina said...

The post is very nicely written and it contains many useful facts. I am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement. Thanks for sharing with us.

Web development company in bangalore
Outsource magento ecommerce services india
ECommerce Website developers in bangalore


chenna sankar said...

Nice post....

Hadoop Training in Chennai

SWETANK SINGH said...

Thanks a lot for sharing marvellous information on sap course.
SAP Basis training institutes in Noida

webgensis mkt said...

Searching for Wordpress Development Company
visit us at webgensis for custom web development services and Hire Wordpress Expert
who code your dreams live.

Shailendra said...

Nice blog Content.It is very informative and helpful. Please share more content. Thanks.
SAP training institute in Gurgaon

Nicholas de said...

Nice blog has been shared by you. before i read this blog i didn't have any knowledge about this but now i got some knowledge so keep on sharing such kind of an interesting blogs.

sap abap online courses

best WordPress Design Company in Surat, India said...

https://www.lathiyasolutions.com/service/wordpress-development

sofianan said...
This comment has been removed by the author.
sofianan said...

Thanks For Your valuable posting, it was very informative.I am working in erp software in chennai If You need any more information kindly make me call to this number 44 45 07 8222.

Pradeep Ogen said...

Ogeninfo is a creative website designing company in Delhi, India. We offer a full range of digital marketing. thanks you for sharing
website designing company in Delhi

john jersy said...

I prefer to study this kind of material. Nicely written information in this post, the quality of content is fine and the conclusion is lovely. Things are very open and intensely clear explanation of issues
Click here:
angularjs training in chennai
Click here:
angularjs2 training in chennai
Click here:
angularjs4 Training in Chennai
Click here:
angularjs5 Training in Chennai
Click here:
angularjs6 Training in Chennai

sai said...

When I initially commented, I clicked the “Notify me when new comments are added” checkbox and now each time a comment is added I get several emails with the same comment. Is there any way you can remove people from that service? Thanks.
Click here:
Microsoft azure training in chennai
Click here:
Microsoft azure training in online
Click here:
Microsoft azure training in tambaram
Click here:
Microsoft azure training in chennai

Anonymous said...

Word press is a best Open Source CMS which allows it to be used free of cost. You can use it on any kind of personal or commercial website without have to pay a single penny for it. It is built on PHP/MySQL (which is again Open Source) and licensed under GPL.
wordpress interview questions

pooja saravanan said...

Nice tutorial. Thanks for sharing the valuable information. it’s really helpful. Who want to learn this blog most helpful. Keep sharing on updated tutorials…
Blueprism training in annanagar

Blueprism training in velachery

Blueprism training in marathahalli


AWS Training in chennai

AWS Training in bangalore

gowsalya said...
This comment has been removed by the author.
sachin.ogeninfo said...

Lyrics with music
English Song lyrics

Chitra devi said...

Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end.

best rpa training in chennai |
rpa training in chennai |
rpa training in bangalore
rpa training in pune | rpa online training

Nila shri said...

Nice information, valuable and excellent design, as share good stuff with good ideas and concepts, lots of great information and inspiration, both of which I need, thanks to offer such a helpful information here.
Data Science Training in Chennai | Data Science training in anna nagar
Data Science training in chennai | Data science training in Bangalore
Data Science training in marathahalli | Data Science training in btm

hansika hans said...

hank you for benefiting from time to focus on this kind of, I feel firmly about it and also really like comprehending far more with this particular subject matter. In case doable, when you get know-how, is it possible to thoughts modernizing your site together with far more details? It’s extremely useful to me 

java training in chennai | java training in USA

Anonymous said...

Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
angularjs-Training in velachery

angularjs Training in bangalore

angularjs Training in bangalore

angularjs Training in btm

angularjs Training in electronic-city

Anjali Siva said...
This comment has been removed by the author.
Anjali Siva said...

Your article gives lots of information to me. I really appreciate your efforts admin, continue sharing more like this.
Microsoft Azure Training
Azure Training center in Chennai
RPA Training in Chennai
R Programming Training in Chennai
DevOps Certification Chennai
ccna Training in Chennai

Anbarasan14 said...

Nice post. Thanks for sharing such a worthy information.

French Class in Mulund
French Coaching in Mulund
French Classes in Mulund East
French Language Classes in Mulund
French Training in Mulund
French Coaching Classes in Mulund
French Classes in Mulund West

aruna ram said...

Very creativity blog!!! I learned a lot of new things from your post. It is really a good work and your post is the knowledgeable. Waiting for your more updates...
Blue Prism Training Institute in Bangalore
Blue Prism Course in Bangalore
Blue Prism Training Bangalore
Blue Prism Classes in Bangalore
Blue Prism Course in Adyar
Blue Prism Training in Mogappair

LindaJasmine said...

Amazing Post . Thanks for sharing. Your style of writing is very unique. Pls keep on updating.
Spoken English Classes in Chennai
Best Spoken English Classes in Chennai
Spoken English Class in Chennai
Spoken English in Chennai
Best Spoken English Class in Chennai
English Coaching Classes in Chennai

sathyaramesh said...

Selenium training in chennai
Selenium training institute in Chennai
iOS Course Chennai
Digital Marketing Training in Chennai
German Training Institutes in Velachery
German Language Classes in Chennai
German Courses in chennai

Vicky Ram said...

Thanks for your contribution in sharing such a useful information. Waiting for your further updates.

ejobsalert
Technology

punitha said...

Nice article I was really impressed by seeing this blog, it was very interesting and it is very useful for me.
Javascript Training in Bangalore
Java script Training in Bangalore
Best Institute for Javascript in Bangalore
Advanced Java Course in Bangalore
Java Coaching Institutes in Bangalore

Gautam krish said...

The blog is well written and Thanks for your information.
Advanced JAVA Training
JAVA Training Classes
Core JAVA Certification
JAVA Language Course
Core JAVA Course

aruna ram said...

Such a wonderful think. Your blog is very nice. Thanks for a marvelous posting!!!
CCNA Course in Bangalore
CCNA Institute in Bangalore
CCNA Training Center in Bangalore
Best CCNA Training Institute in Bangalore
CCNA Training in Tnagar
CCNA Course in Vadapalani
CCNA Training in Nungambakkam
CCNA Course in Kodambakkam

Gautam krish said...

The blog is well written and Thanks for your information.
Advanced JAVA Training
JAVA Training Classes
Core JAVA Certification
JAVA Language Course
Core JAVA Course

Bee Yes said...

Amazing Article ! I have bookmarked this article page as i received good information from this. All the best for the upcoming articles. I will be waiting for your new articles. Thank You ! Kindly Visit Us @ Coimbatore Travels | Ooty Travels | Coimbatore Airport Taxi | Coimbatore taxi

Riya Raj said...

Wonderful blog!!! Thanks for your information… Waiting for your upcoming data.
Ethical Hacking Course in Coimbatore
Hacking Course in Coimbatore
Ethical Hacking Training in Coimbatore
Ethical Hacking Training Institute in Coimbatore
Ethical Hacking Training
Ethical Hacking Course

mercyroy said...

Nice idea,keep sharing your ideas with us.i hope this information's will be helpful for the new learners.
Selenium training near me
Selenium Training in Chennai
Selenium Training in OMR
Selenium Training in Sholinganallur

Ram priya said...

This blog is the general information for the feature. You got a good work for these blog.We have a developing our creative content of this mind.Thank you for this blog. This for very interesting and useful.
Data Science course in rajaji nagar
Data Science with Python course in chenni
Data Science course in electronic city
Data Science course in USA
Data science course in pune | Data Science Training institute in Pune

kayal m said...

Great blog!!! It was very impressed to me. I like so much and keep sharing. Thank you.
Robotics Courses in Bangalore
Automation Courses in Bangalore
RPA Courses in Bangalore
Robotics Classes in Bangalore
Robotics Training in Bangalore
Automation Training in Bangalore

SAP Globe said...

Your article is awesome! How long does it take to complete this article? I have read through other blogs, but they are cumbersome and confusing. I hope you continue to have such quality articles to share with everyone! I believe there will be many people who share my views when they read this article from you!

SAP Basis Training | SAP Training








kayal m said...

Good work, really very great information and good creativities. Thank you for your wonderful post!
Digital Marketing Course in Tnagar
Digital Marketing Training in Tnagar
Digital Marketing Classes near me
Digital Marketing Training in Navalur
Digital Marketing Training in Omr
Digital Marketing Course in Omr

elsalmy comp said...

Furniture Moving Company*Insect Control Company*Insulation Company*Company inspection Villas*Water leak detection company*Company Cleaning Villas*home*Furniture Moving Company

Mobile app Development company in Noida said...

Thanks for sharing this blog, this blog is very helpful information for every one.

sathyaramesh said...

Thanks for sharing such a nice info.I hope you will share more information like this. please keep on sharing!
SEO Training
SEO Course in Chennai
SEO Training Institute in Chennai
Best digital marketing course in chennai
Digital marketing course chennai
Digital Marketing Training Institutes in Chennai

jeeva said...

Really very nice blog information for this one and more technical skills are improve,i like that kind of post.

rpa training in btm | rpa training in kalyan nagar | rpa training in electronic city | rpa training in chennai | rpa online training | rpa training in bangalore

School Management Software in Delhi said...

Most impressive Topic and Blog, this is very helpful Information. thanks for sharing.

Afreen said...

The post was amazing. It showcases your knowledge on the topic. Thanks for Posting.
CPHQ Online Training in Kabul. Get Certified Online|
CPHQ Training Classes in Al Farwaniyah

Tips Pengobatan Hernia/Usus Turun said...

Thank you for the various information, hopefully useful for everyone

Obat Untuk Mengeringkan Luka Pasca Operasi
Tips Pengobatan Untuk Menghilangkan Vitiligo
Cara Mengobati Bab Keluar Darah
Pengobatan Atasi Infeksi Pernapasan (Croup)
Suplemen Penyubur Kandungan