6 Choices for a localhost Web Development Environment

For web development, the bare minimum you need access to is AMP:
  1. Apache server
  2. MySQL database
  3. PHP programming language
You can install these as a collection on your computer locally using various OS-specific installations:
  1. Windows: WAMP
  2. Mac: MAMP
  3. Linux: LAMP
  4. Cross-platform: XAMPP
Or, if you prefer an auto-installerBitnami is an excellent option. (And Softaculous also looks promising.) Wikipedia also lists plenty of other Apache, MySQL, and PHP bundles if you're interested in checking out any of the other ones, but in this post, I've taken screenshots of each major offering for you to compare:

#1. WAMP

WAMP homepage and server window
WAMP Server Homepage

#2. MAMP

MAMP homepage and server window
MAMP Server Homepage

#3. LAMP

LAMP Wikipedia and install
LAMP Software Bundle on Wikipedia
As the above picture indicates, if you want a straight up LAMP installation, you'll likely be doing it all piece-by-piece - or through your Linux distribution's get or yum installers. But if you're a Linux user, you're probably already comfortable with that kind of thing. Here are instructions for installing LAMP on various Linux distributions (source: Wikipedia):


XAMPP homepage and server window
XAMPP Server Homepage


AMPPS homepage and server window
AMPPS Homepage

#6. Bitnami

Bitnami homepage and server window
Bitnami Homepage
I've personally used WAMP, MAMP, and XAMPP and none has really been disappointing.
  • XAMPP is slightly more complicated and has more features (but that's to be expected because it's a Linux program as well).
  • WAMP is a good and simple option for Windows - I've used it with my high school students.
  • MAMP is a clean and simple option for Mac and I've used it exclusively on Mac before.
  • MAMP PRO is also a good option if you're willing to pay a little bit because it allows multiple WordPress installations on the same localhost.
However, recently, I've been using Bitnami quite a bit on the recommendation of Morten Rand-Hendriksen, from Lynda.com, and I've quite enjoyed it. It's very easy to download and install and the Server Manager program is very clean and well designed. It's a simple one-click START or STOP for your servers and a one-click ACCESS SITE to go to your localhost install right from the Manager. Which installation do you prefer? Leave me a comment with your thoughts. This post has been modified slightly from my original post on aaronsnowberger.com

Default WordPress Theme Customizer Controls

I've recently been messing around with the WP Theme Customizer a bunch and have been looking for the names of all the default settings, sections, and controls. I found them in a file in the wp-includes folder:
The various default section names, setting names, and 'priority' are listed below.This is mostly useful if you're trying to simply rearrange the position ('priority' => 20) of some options, or want to rename some of them like so:
$wp_customize->get_section( 'nav' )->title = __( 'Menus', 'theme_slug' );
$wp_customize->get_control( 'blogname' )->priority = 10;
$wp_customize->get_setting( 'background_color' )->default = '#169A70';
  1. Site Title & Tagline ('title_tagline'), 20
    1. 'blogname'
    2. 'blogdescription'
    3. 'display_header_text'
  2. Colors ('colors'), 40
    1. 'header_textcolor'
    2. 'background_color'
  3. Header Image ('header_image'), 60
    1. 'header_image'
    2. 'header_image_data'
  4. Background Image ('background_image'), 80
    1. 'background_image_thumb'
    2. 'background_repeat'
    3. 'background_position_x'
    4. 'background_attachment'
  5. Navigation ('nav'), 100
    1. "nav_menu_locations[{$location}]"
  6. Widgets ('widgets'), 110
  7. Static Front Page ('static_front_page'), 120
    1. 'show_on_front'
    2. 'page_on_front'
    3. 'page_for_posts'
The code specifically for 'widgets' is located in:
The full code for the default Theme Customizer settings is here:
 * Register some default controls.
 * @since 3.4.0
 public function register_controls() {

 /* Control Types (custom control classes) */
 $this->register_control_type( 'WP_Customize_Color_Control' );
 $this->register_control_type( 'WP_Customize_Upload_Control' );
 $this->register_control_type( 'WP_Customize_Image_Control' );
 $this->register_control_type( 'WP_Customize_Background_Image_Control' );

 /* Site Title & Tagline */

 $this->add_section( 'title_tagline', array(
 'title' => __( 'Site Title & Tagline' ),
 'priority' => 20,
 ) );

 $this->add_setting( 'blogname', array(
 'default' => get_option( 'blogname' ),
 'type' => 'option',
 'capability' => 'manage_options',
 ) );

 $this->add_control( 'blogname', array(
 'label' => __( 'Site Title' ),
 'section' => 'title_tagline',
 ) );

 $this->add_setting( 'blogdescription', array(
 'default' => get_option( 'blogdescription' ),
 'type' => 'option',
 'capability' => 'manage_options',
 ) );

 $this->add_control( 'blogdescription', array(
 'label' => __( 'Tagline' ),
 'section' => 'title_tagline',
 ) );

 /* Colors */

 $this->add_section( 'colors', array(
 'title' => __( 'Colors' ),
 'priority' => 40,
 ) );

 $this->add_setting( 'header_textcolor', array(
 'theme_supports' => array( 'custom-header', 'header-text' ),
 'default' => get_theme_support( 'custom-header', 'default-text-color' ),

 'sanitize_callback' => array( $this, '_sanitize_header_textcolor' ),
 'sanitize_js_callback' => 'maybe_hash_hex_color',
 ) );

 // Input type: checkbox
 // With custom value
 $this->add_control( 'display_header_text', array(
 'settings' => 'header_textcolor',
 'label' => __( 'Display Header Text' ),
 'section' => 'title_tagline',
 'type' => 'checkbox',
 ) );

 $this->add_control( new WP_Customize_Color_Control( $this, 'header_textcolor', array(
 'label' => __( 'Header Text Color' ),
 'section' => 'colors',
 ) ) );

 // Input type: Color
 // With sanitize_callback
 $this->add_setting( 'background_color', array(
 'default' => get_theme_support( 'custom-background', 'default-color' ),
 'theme_supports' => 'custom-background',

 'sanitize_callback' => 'sanitize_hex_color_no_hash',
 'sanitize_js_callback' => 'maybe_hash_hex_color',
 ) );

 $this->add_control( new WP_Customize_Color_Control( $this, 'background_color', array(
 'label' => __( 'Background Color' ),
 'section' => 'colors',
 ) ) );

 /* Custom Header */

 $this->add_section( 'header_image', array(
 'title' => __( 'Header Image' ),
 'theme_supports' => 'custom-header',
 'priority' => 60,
 ) );

 $this->add_setting( new WP_Customize_Filter_Setting( $this, 'header_image', array(
 'default' => get_theme_support( 'custom-header', 'default-image' ),
 'theme_supports' => 'custom-header',
 ) ) );

 $this->add_setting( new WP_Customize_Header_Image_Setting( $this, 'header_image_data', array(
 // 'default' => get_theme_support( 'custom-header', 'default-image' ),
 'theme_supports' => 'custom-header',
 ) ) );

 $this->add_control( new WP_Customize_Header_Image_Control( $this ) );

 /* Custom Background */

 $this->add_section( 'background_image', array(
 'title' => __( 'Background Image' ),
 'theme_supports' => 'custom-background',
 'priority' => 80,
 ) );

 $this->add_setting( 'background_image', array(
 'default' => get_theme_support( 'custom-background', 'default-image' ),
 'theme_supports' => 'custom-background',
 ) );

 $this->add_setting( new WP_Customize_Background_Image_Setting( $this, 'background_image_thumb', array(
 'theme_supports' => 'custom-background',
 ) ) );

 $this->add_control( new WP_Customize_Background_Image_Control( $this ) );

 $this->add_setting( 'background_repeat', array(
 'default' => get_theme_support( 'custom-background', 'default-repeat' ),
 'theme_supports' => 'custom-background',
 ) );

 $this->add_control( 'background_repeat', array(
 'label' => __( 'Background Repeat' ),
 'section' => 'background_image',
 'type' => 'radio',
 'choices' => array(
 'no-repeat' => __('No Repeat'),
 'repeat' => __('Tile'),
 'repeat-x' => __('Tile Horizontally'),
 'repeat-y' => __('Tile Vertically'),
 ) );

 $this->add_setting( 'background_position_x', array(
 'default' => get_theme_support( 'custom-background', 'default-position-x' ),
 'theme_supports' => 'custom-background',
 ) );

 $this->add_control( 'background_position_x', array(
 'label' => __( 'Background Position' ),
 'section' => 'background_image',
 'type' => 'radio',
 'choices' => array(
 'left' => __('Left'),
 'center' => __('Center'),
 'right' => __('Right'),
 ) );

 $this->add_setting( 'background_attachment', array(
 'default' => get_theme_support( 'custom-background', 'default-attachment' ),
 'theme_supports' => 'custom-background',
 ) );

 $this->add_control( 'background_attachment', array(
 'label' => __( 'Background Attachment' ),
 'section' => 'background_image',
 'type' => 'radio',
 'choices' => array(
 'scroll' => __('Scroll'),
 'fixed' => __('Fixed'),
 ) );

 // If the theme is using the default background callback, we can update
 // the background CSS using postMessage.
 if ( get_theme_support( 'custom-background', 'wp-head-callback' ) === '_custom_background_cb' ) {
 foreach ( array( 'color', 'image', 'position_x', 'repeat', 'attachment' ) as $prop ) {
 $this->get_setting( 'background_' . $prop )->transport = 'postMessage';

 /* Nav Menus */

 $locations = get_registered_nav_menus();
 $menus = wp_get_nav_menus();
 $num_locations = count( array_keys( $locations ) );

 $this->add_section( 'nav', array(
 'title' => __( 'Navigation' ),
 'theme_supports' => 'menus',
 'priority' => 100,
 'description' => sprintf( _n('Your theme supports %s menu. Select which menu you would like to use.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . "\n\n" . __('You can edit your menu content on the Menus screen in the Appearance section.'),
 ) );

 if ( $menus ) {
 $choices = array( 0 => __( '— Select —' ) );
 foreach ( $menus as $menu ) {
 $choices[ $menu->term_id ] = wp_html_excerpt( $menu->name, 40, '…' );

 foreach ( $locations as $location => $description ) {
 $menu_setting_id = "nav_menu_locations[{$location}]";

 $this->add_setting( $menu_setting_id, array(
 'sanitize_callback' => 'absint',
 'theme_supports' => 'menus',
 ) );

 $this->add_control( $menu_setting_id, array(
 'label' => $description,
 'section' => 'nav',
 'type' => 'select',
 'choices' => $choices,
 ) );

 /* Static Front Page */
 // #WP19627

 $this->add_section( 'static_front_page', array(
 'title' => __( 'Static Front Page' ),
 // 'theme_supports' => 'static-front-page',
 'priority' => 120,
 'description' => __( 'Your theme supports a static front page.' ),
 ) );

 $this->add_setting( 'show_on_front', array(
 'default' => get_option( 'show_on_front' ),
 'capability' => 'manage_options',
 'type' => 'option',
 // 'theme_supports' => 'static-front-page',
 ) );

 $this->add_control( 'show_on_front', array(
 'label' => __( 'Front page displays' ),
 'section' => 'static_front_page',
 'type' => 'radio',
 'choices' => array(
 'posts' => __( 'Your latest posts' ),
 'page' => __( 'A static page' ),
 ) );

 $this->add_setting( 'page_on_front', array(
 'type' => 'option',
 'capability' => 'manage_options',
 // 'theme_supports' => 'static-front-page',
 ) );

 $this->add_control( 'page_on_front', array(
 'label' => __( 'Front page' ),
 'section' => 'static_front_page',
 'type' => 'dropdown-pages',
 ) );

 $this->add_setting( 'page_for_posts', array(
 'type' => 'option',
 'capability' => 'manage_options',
 // 'theme_supports' => 'static-front-page',
 ) );

 $this->add_control( 'page_for_posts', array(
 'label' => __( 'Posts page' ),
 'section' => 'static_front_page',
 'type' => 'dropdown-pages',
 ) );

Quick Tip: You have reached a domain that is pending ICANN verification

icann-registration-pending Just tried to log into one of my client's websites this morning and was met with the lovely notification you see here. I've never encountered this before on any of the other sites I've built. So, why am I seeing this now? Apparently, the domain owner's name and email address were never verified via the follow-up email they sent out after the domain was registered. Here's what Ryan Your Tech Guy says:
The domain has to be verified. You will have to verify the domain with the email sent to the whois contact email. Once you have verified the domain, ICANN will un-suspend the domain.
So, if you find yourself facing a similar message one day when trying to visit or work on your site (or any other site for that matter), do yourself a favor and (1) check your email, then (2) verify your contact info (or be helpful and "resend verification email" to the site owner - hopefully with an Inbox full of those emails, they'll remember to click on one to verify their info). Here's some additional info:
  1. Dreamhost's Official Verification Policy
  2. Ryan Your Tech Guy's Write-up
  3. TechRepublic's News Article
(Actually, I'm a bit surprised to be seeing this now. I've worked on and built up the site since July 2014. Why suspend it after 6 months of production? Why not earlier?)

Quick Tip: WordPress Site Hacked? Follow These Links

One KEY thing to keep in mind BEFORE a hack:

Always have a backup.

BackWPup is a great (free) plugin that's super-easy to use and setup automatic backups to Dropbox and other Cloud storage services. I use it on all my sites and highly recommend it (Multi-site compatible as well).
The following was originally posted by a Volunteer moderator on the WordPress.org forums, but they are great links worth keeping a copy of for later reference: You need to start working your way through these resources: Additional Resources:

Quick Tip: Use Chrome’s Emulator Tool for Better Development

Google Chrome has a pretty nifty emulator tool that enables better website development by emulating the different devices that you would want to test your websites on. A few keys points about the emulator that makes it unique and much better for development than merely stretching your browser window to various sizes:
  1. Chrome's minimum browser width (400px) is still wider than the smallest device size (320px iPhone 3/4)
  2. Using the emulator tool also changes the user agent variable in Chrome so that it thinks and acts as if it were the actual device it is emulating
  3. The emulator shows a grid and rulers with pixel dimensions behind the device window

How to use the Chrome Emulator?

  1. Open the Element Inspector (right-click "Inspect Element")
  2. Click on the mobile device icon in the upper-left corner of the Element Inspector (see screenshot)
  3. Select the device you wish to emulate from the dropdown menu at the top (see screenshot)
  4. Tip: Refresh the page for proper user agent spoofing and viewport rendering
1. Open the Element Inspector and click the mobile device icon
2. Select the device you wish to emulate from the dropdown menu
WordPress plugin SEO by Yoast

Quick Tip: Learn the basics of SEO and non-coding WordPress Customization

WordPress currently powers over 23% of ALL the world's websites. It powers sites such as CNN, Jay-Z, and Mashable.

So, you want a highly customizable site without coding?

Divi WordPress Drag and Drop Theme
Divi WordPress Drag and Drop Theme
Find a drag-and-drop Theme like Divi or Enfold for something easier to build (no code - EXTREMELY customizable). You'll need to go self-hosted (no more WordPress.com).

You want easy SEO?

WordPress plugin SEO by Yoast
WordPress plugin SEO by Yoast
For SEO, sign up for Google Analytics to start tracking your site and learning which keywords attract visitors. Also, get a good couple of good WP plugins like SEO by Yoast (which is the highest ranked and most downloaded SEO plugin for WP in history). Also get Google Analytics by Yoast for better tracking. Here's the Definitive Guide to WordPress SEO by Yoast.

You want to learn the basics of SEO tactics?

Jon Duckett's HTML & CSS book
Jon Duckett's HTML & CSS book
I recently read through HTML & CSS by Jon Duckett and it has a simple (though comprehensive) 2-page walkthrough on SEO. The basic things you should know are:
  1. On-site SEO tactics and
  2. Off-site SEO tactics

On-site SEO tactics include:

Having your targeting keywords appear in every:
  1. Page <title>
  2. URL
  3. Headings <h1>
  4. Body text 2-3 times each
  5. Hyperlinks  (make them descriptive, not just "click here")
  6. Image <alt> attributes
  7. Page <meta> description
(The Yoast SEO plugin takes care of ALL of this for you on a page-by-page basis).

Off-site SEO tactics include:

Getting links IN to your site from other (relevant) sites. You can do this through:
  1. Social Media sharing (and enabling social sharing buttons with other plugins)
  2. Commenting (and ADDING VALUE) on other blogs in your industry with a link back to your site (no spam and no "Nice post" stuff either)
  3. Guest posting on other blogs with a link back to your site.
Hope this helps you build a better website!~

Coming Soon!

Hi! My name is Aaron Snowberger and I'm a WordPress Plugin author! I also teach English to university students in Korea, teach Basic Computer and Programming Literacy classes to Korean high schoolers (in English), and teach problem solving for logic puzzles to elementary Korean students. I've lived in Korea for 8 years now, but what I'm really passionate about is simple, clean, intuitive print and WordPress design.

Homepage Coming Soon!

With the Initial Release of my FIRST WordPress plugin in the WP Plugins repository, I've decided to completely revamp my online web presence to better reflect (and appropriate) my current online undertakings. In the near future (launching in 2015), this site will be the homepage for ALL my WordPress related development, tutorials, plugins, themes, and so on.
    Expect to see:
  • Themes, demos, and downloads I'll begin my Theme releases with a relaunch of THIS "Launch" page for this site.
  • Plugins This site will house the full JKL Plugin archive, help docs, demos, and so on.
  • Support Forum Additionally, I will (probably) host a support forum for all the plugins and themes I release (or else, I'll redirect support back over to WordPress.org).
  • WP Development Tutorials As I'm progressing along with WP Development, I'm learning a lot - so in order to help me better remember it, I'll be sharing as I go with you (the readers).

Launching 2015

But for now, you can find me on WordPress.org @ jekkilekki
  • 1
  • 2