Select Your Favourite
Category And Start Learning.

Course Content
02 Creating the Base Theme
03 Making the Base Theme WooCommerce Compatible
04 Adding a Blog to the Theme
05 Internationalization, Security and Coding Standards
06 Bonus Section – Submitting the Theme to WordPress.org
07 Conclusion
woocommerce wordpress theme development
About Lesson

 New items will be added as important questions will arise

1) I can’t access localhost after moving my htdocs folder to the Documents directory on my Mac. It says “Access forbidden”.

The problem is that the new MacOSX Catalina is implementing some restrictions to the special user folders (Documents, Desktop, Downloads for example). So one of the solutions is use another location to your htdocs directory. For example, I’ve moved my htdocs to my user folder: /User/marcelovieira/htdocs.

Of course, after moving the folder, you’ll need to repeat all of the instructions given in the course. You’ll need to open the httpd.conf file once again and change the two lines under DocumentRoot and Directory. Mine is like this now:

DocumentRoot "/Users/marcelovieira/htdocs"
<Directory "/Users/marcelovieira/htdocs">

And, of course, you’ll need to give read and write permissions to the new folder.

2) After WooCommerce plugin installation, default WooCommerce pages are not included

If the default WooCommerce pages (checkout/car/my account etc) are not automatically created after WooCommerce installation, you can regenerate them by following these steps:

  • Go to WooCommerce -> Status

  • Choose the “Tools” tab

  • Look for “Create default WooCommerce pages” and click on the “Create pages” button.

This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.

3) The “on sale” span is not in the right position, even in the source code. How can I fix it?

As you’ll see in the video lessons (starting from lesson #30 – Modifying the single-product.php file), it looks like the “on sale” span is displaying correctly. But some students have reported that it’s not.

To fix the issue, just modify the CSS for the span. Here are the new values:

.woocommerce ul.products li.product .onsale{ 
    top: 16px; 
    right: 0;
    left: 0; /* Modified - was: auto */ 
    transform: rotate(90deg); 
    border-radius: 0; 
    width: 83px; 
    padding: 0; 
    background-color: #D2335B; 
    margin: 0; 
    font-weight: 400;  
}

Thanks students Annete Jonsson and Andràs Marghescu for the solution!

4) I see a message to update the theme while creating it for the first time. Do I need to update it?

This message is shown because the theme created in this course was submitted to WordPress.org at the end of this course. Since then, it is being constantly updated in the WordPress repository.

This only occurs because the folder you are creating in the course has the same name as the file submitted to WordPress.org.

There is no way to avoid this. So simply ignore the messages that ask you to update the theme and proceed.

5) I can’t see the CSS changes I make

This is a cache related issue. There are some things you can do to avoid this behaviour. 

a) try to work on a private window (incognito window)

b) on Firefox or Chrome, press Cmd+option+I (Ctrl+Shift+I), then F1. On Chrome, Under Network, choose “Disable cache (while DevTools is open). On Firefox, under Advanced Settings, choose “Disable HTTP Cache (when toolbox is open)”

c) force reload pressing Ctrl+Shift+R (or Ctrl+F5) instead of only pressing F5 or Ctrl+R

d) You can also use this approach while developing the theme (only do this while developing the theme; after you’re done with the theme development, undo the changes): https://developer.wordpress.org/reference/functions/wp_enqueue_style/#comment-2056

6) I’m getting errors such as “Fatal error: Allowed memory size of 134217728 bytes exhausted”. How can I fix it?

Reason #1

This is not related to WordPress itself. It has to do with your server configuration.

To fix this issue, open up your file explorer. Go to C:xamppphp (MacOS: Applications/Xampp/xamppfiles/etc) and open a file called php.ini. I prefer using Sublime Text to edit this file.

Look for an entry called memory_limit. Mine is like this and is working like a charm:

memory_limit=128M 

You might as well change the following entries:

max_execution_time=30
max_input_time=60
upload_max_filesize=128M

After making those changes, save the file.

Now go to your Xampp control panel and restart the Apache Web Server.

The problem might disappear now.

Reason #2

Many students have noticed that this error is also occurring when the wp_enqueue_script() function is spelled wrong in the functions.php file. The correct syntax is wp_enqueue_script, not wp_enqueue_scripts. Just drop the final letter S, right…

7) Why do I need to create the wp-config file manually everytime I install WordPress?

THE FOLLOWING STEPS ARE FOR MAC OSX AND LINUX USERS ONLY. IF YOU ARE ON A WINDOWS MACHINE, THIS WILL NOT HELP YOU.

That’s an ownership problem. You can solve it permanently moving your htdocs folder to another place and changing your webserver default user. This last change will also help you if WordPress keeps asking for the FTP credentials when you try to install a plugin.

A – Moving your htdocs folder somewhere else

This will help you if you see a message saying “Sorry, but I can’t write the wp-config.php file” when you are installing WordPress. This happens because your default user doesn’t have permission to write to the xampp/htdocs folder on MacOSX. On Linux, you won’t even be able to create a folder inside /opt/lampp/htdocs.

So, let’s move that folder to another place. For example, you can move it to the Documents folder. 

First, create a folder called htdocs into your users folder.

Go to your Xampp control panel, Manage Servers, choose Apache Web Server. Click on “Configure”. Click on “Open Conf File”. Yes.

Look for this code snippet:

DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs"
<Directory "/Applications/XAMPP/xamppfiles/htdocs">

Now you need to replace those values with the path to your users folder. In my case, for example, that would be:

DocumentRoot "/Users/marcelovieira/htdocs"
<Directory "/Users/marcelovieira/htdocs">

Don’t close the file yet. We still need to make some changes.

B – Changing the webserver default user

By default, the webserver user which runs the httpd service is _www or daemonwhich will not be the user in your local account. But if your machine is only in use by you and the webserver will run only under your account then you can change the user. 

This can also help you if WordPress keeps asking for the FTP credentials when you try to install a plugin.

Still on the httpd.conf file, look for these lines:

User daemon
Group daemon

You need to change the user/group daemon by your own user and group. To do that, open your terminal, type “id” (without the quotation marks) and hit enter.

The first results will be something like this: 

uid=501(marcelovieira) gid=20(staff) groups=20(staff) 

You’ll need the usernames for uid and gid. 

Now, comment out the original values on your httpd.conf file. Duplicate those two lines, uncomment them and replace the daemon user with the ones you found on uid and gid. Something like this:

#User daemon 
#Group daemon

User marcelovieira 
Group staff

Now you can go to File->Save.

Restart your Apache Web Server. You can use the xampp control panel to do this.

Now, open your new htdocs folder in Finder. Right click and choose “Get Info”. 

Under “Sharing & Permissions”, change the user privileges to “Read & Write” for every user. 

Ok, done! Now you can go ahead and try to install WordPress again. From now on you’ll be creating all of your new projects into your new htdocs folder. Forget about Applications/Xampp/htdocs (on Mac) or /opt/lampp/htdocs (on Linux).

Source: https://coolestguidesontheplanet.com/set-virtual-hosts-apache-mac-osx-10-10-yosemite/#apacheuser

8) My image size is not exactly as it shows in the video lessons

If your slider images are not being cropped to the right size (as you see on lecture #46), you can force WordPress to recreate the thumbnails.

I’m not sure yet why that happens, but sometimes WordPress only create thumbnails based on newly created image sizes (via add_image_size() function) for newly uploaded images.

To solve that, you can delete the thumbnail images and upload the same files again, or you can try any of the available plugins for regenerating thumbnails.

Thanks, student Bruno Penner for the collaboration!

9) Can I validate the “Deal of the Week Product ID” field, so that it doesn’t display a warning whenever the product has no sale price?

Yes, it is possible. You can add a validation callback function to the ‘set_deal’ field, like this:

$wp_customize->add_setting(
   'set_deal', array(
      'type'               => 'theme_mod',
      'default'            => '',
      'sanitize_callback'  => 'absint',
      'validate_callback'  => 'validate_sale_price'
   )
);
function validate_sale_price( $validity, $product ) {
   $sale_validation = get_post_meta( $product, '_sale_price', true );
   if ( empty( $sale_validation ) ):
   	  /* translators: 1: product ID number */
      $validity->add( 'sale_price_not_set', sprintf( __( 'Please Add Sale Price - Product ID: %1$s', 'fancy-lab' ), $product ) );
   endif;
   return $validity;
}

The complete discussion about the subject can be found here: https://www.udemy.com/course/woocommerce-wordpress-theme-development/learn/#questions/9000514/

Thanks, once again, student Kalman Pinter for the solution!

10) Can you make the add to cart button in the “Deal of the Week” section work with Ajax?

Yes, you should modify the link code as follows:

<a href="<?php echo esc_url( '?add-to-cart=' . $deal ); ?>" data-quantity="1" class="add-to-cart button product_type_simple add_to_cart_button ajax_add_to_cart" data-product_id="<?php echo esc_attr( $deal ); ?>" aria-label="Add “<?php echo esc_attr( get_the_title( $deal ) ) ?>” to your cart" rel="nofollow"><?php esc_html_e( 'Add to Cart', 'fancy-lab' ) ?></a>

11) The “Deal of the Week” section is displaying an error when a grouped product or a product with variations is selected. How can I fix that?

WooCommerce has other types of products other than the simple one. It also has external, variable and grouped products. You need to handle each one of them differently when creating links.

First, let’s create a new variable to to help us identify what product type we want to work with.

Let’s add another variable called $price_variable to get the prices for each variation (line 7). Then, let’s create another variable called $products and pass our $deal variable as a parameter (line 10):

// Getting data from Customizer to display the Deal of the Week section
$showdeal 			= get_theme_mod( 'set_deal_show', 0 );
$deal 				= get_theme_mod( 'set_deal' ); 
$currency 			= get_woocommerce_currency_symbol();
$regular 			= get_post_meta( $deal, '_regular_price', true);
$sale 				= get_post_meta( $deal, '_sale_price', true);
$price_variable			= get_post_meta( $deal, '_price', false);

// Global WooCommerce product
$product = wc_get_product( $deal );

// We'll only show this section if the user chooses to do so and if some deal product is set
if( $showdeal == 1 && ( !empty( $deal )) ):
	// We want to avoid showing empty percentage values for variable products
	if( !empty( $regular ) && !empty( $sale ) ):
		$discount_percentage 	= absint( 100 - ( ( $sale/$regular ) * 100) );
	endif;

Now, variable and grouped products are very tricky. To begin with, we can’t set a sale price for a grouped product, only for its individual items. In the other hand, product variations are stored with a distinct ID in the database. So prices for variable products are also set individually, not for the variable product itself, but for each of its variations.

So, first of all, we will display prices for variable products differently, since we can select them in Customizer (!!!provided they have at least one product with a sale price!!!), but there’s no price to be displayed for the wrapper product, only for the variations So the prices div will stay like this (notice the variations’ prices within the else portion of the code – lines 21 to 38):

<div class="prices">
	<span class="regular">
		<?php 
		// We only show prices for non-variable products
		if ( ! $product->is_type( 'variable' ) ) {
			echo esc_html( $currency ); 
			echo esc_html( $regular ); 
		}
		?>
	</span>
	<?php if( !empty( $sale ) ): ?>
		<span class="sale">
			<?php 
			// We only show prices for non-variable products
			if ( ! $product->is_type( 'variable' ) ) {
				echo esc_html( $currency );
				echo esc_html( $sale ); 
			}
			?>
		</span>
		<?php else: ?>
			<span class="sale">
			<?php 
			// We need to care about variable products
			if ( $product->is_type( 'variable' ) ) {
				$i = 0;
				foreach( $price_variable as $variable ){
					if($i == 0 && ( $product->get_variation_sale_price( 'max' ) != $product->get_variation_sale_price( 'min' ) ) ){
						echo esc_html( $currency . $variable ) . ' - '; 
					}else{
						echo esc_html( $currency . $variable );
					}
					$i++;
				}
			}
			?>
		</span>											
	<?php endif; ?>
</div>

Another thing we need to take extra care is the link below the prices, that add products to the cart. External products can’t be sent to cart. Variable products are the same, and they need to display a link to select options. For grouped products, we can only select each individual items that has sale prices.

To display the correct link, the code for the button needs to be updated like this:

<?php if( $product->is_type( 'variable' ) ): ?>
	<a href="<?php echo esc_url( get_permalink( $deal ) ) ?>" data-quantity="1" class="add-to-cart button product_type_variable add_to_cart_button" data-product_id="<?php echo esc_attr( $deal ); ?>" aria-label="Select options for “<?php echo esc_attr( get_the_title( $deal ) ) ?>”" rel="nofollow"><?php esc_html_e( 'Select options', 'fancy-lab' ) ?></a>
<?php elseif( $product->is_type( 'external' ) ): ?>
	<a href="<?php echo esc_url( get_permalink( $deal ) ) ?>" data-quantity="1" class="add-to-cart button product_type_variable add_to_cart_button" data-product_id="<?php echo esc_attr( $deal ); ?>" aria-label="View details for “<?php echo esc_attr( get_the_title( $deal ) ) ?>”" rel="nofollow"><?php esc_html_e( 'View details', 'fancy-lab' ) ?></a>
<?php else: ?>
	<a href="<?php echo esc_url( '?add-to-cart=' . $deal ); ?>" data-quantity="1" class="add-to-cart button product_type_simple add_to_cart_button ajax_add_to_cart" data-product_id="<?php echo esc_attr( $deal ); ?>" aria-label="Add “<?php echo esc_attr( get_the_title( $deal ) ) ?>” to your cart" rel="nofollow"><?php esc_html_e( 'Add to Cart', 'fancy-lab' ) ?></a>
<?php endif; ?>

EXTRA INFO:

Optionally, you can create a custom dropdown control to select the items within the Customizer. First, create a new file called custom-controls.php and require it at the beginning of your customizer.php file:

require_once 'custom-controls.php';

Then, in the new file, add the following code:

if( class_exists( 'WP_Customize_Control' ) ):

	/*
	 * Create a dropdown with products on sale
	 * */ 

	class Fancy_Lab_Sale_Products_Dropdown_Control extends WP_Customize_Control {

		public $type = 'on-sale-products-dropdown';

		public function render_content() {

		/** 
		* Get only on sale products. This will only work if WooCommerce is installed
		* It is not a problem, since this control will be used only in that situation
		* See customizer.php to understand why
		*/ 
		$query_args = array(
		    'no_found_rows'     => 1,
		    'post_status'       => 'publish',
		    'post_type'         => 'product',
		    'meta_query'        => WC()->query->get_meta_query(),
		    'post__in'          => array_merge( array( 0 ), wc_get_product_ids_on_sale() )
		);
		$onsale = new WP_Query( $query_args );

		?>
			<label>
				<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
				<select <?php $this->link(); ?>>
					<?php 
						while( $onsale->have_posts() ) {
							$onsale->the_post();
							echo '<option value="' . esc_attr( get_the_ID() ) . '"' . selected( $this->value(), esc_attr( get_the_ID() ) ) . '>' . esc_attr( the_title( '', '', false ) ) . '</option>';
						}
					?>
				</select>
			</label>
		<?php
		}
	}

	
endif;

Then, in customizer.php, build the field like this:

// Deal of the Week Product to Display
$wp_customize->add_setting( 
	'set_deal', array(
		'type'				=> 'theme_mod',
		'default'			=> 0,
		'sanitize_callback'		=> 'absint',
	) 
);

$wp_customize->add_control( 
	new Fancy_Lab_Sale_Products_Dropdown_Control( 
		$wp_customize, 
		'set_deal', array(
			'section'	=> 'sec_home_page',
			'label'		=> __( 'Deal of the Week Product to Display', 'fancy-lab' ),
		) 
	) 
);
0% Complete