<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SkyVerge</title>
	<atom:link href="http://www.skyverge.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.skyverge.com</link>
	<description>Premium WooCommerce Extensions / Consulting</description>
	<lastBuildDate>Thu, 23 May 2013 20:23:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>How to Use WooCommerce 2.0 Lightbox</title>
		<link>http://www.skyverge.com/blog/how-to-use-woocommerces-lightbox-part-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-use-woocommerces-lightbox-part-2</link>
		<comments>http://www.skyverge.com/blog/how-to-use-woocommerces-lightbox-part-2/#comments</comments>
		<pubDate>Fri, 10 May 2013 01:35:10 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[lighbox]]></category>
		<category><![CDATA[woocommerce 2.0]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1625</guid>
		<description><![CDATA[<p>WooCommerce 2.0 comes with prettyPhoto, a Lightbox implementation, bundled as part of the core. It&#8217;s used on the product pages to display the image gallery pictures, and a common question is &#8220;How do I use WooCommerce&#8217;s lightbox to do X&#8221;. This article will walk you through how to do just that. Enable Lightbox The first [...]</p><p>The post <a href="http://www.skyverge.com/blog/how-to-use-woocommerces-lightbox-part-2/">How to Use WooCommerce 2.0 Lightbox</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.woothemes.com/woocommerce/">WooCommerce 2.0</a> comes with <a href="http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/">prettyPhoto</a>, a Lightbox implementation, bundled as part of the core.  It&#8217;s used on the product pages to display the image gallery pictures, and a common question is &#8220;How do I use WooCommerce&#8217;s lightbox to do X&#8221;.  This article will walk you through how to do just that.</p>
<h2>Enable Lightbox</h2>
<p>The first step is to ensure that the Lightbox is enabled by going to WooCommerce &gt; Settings &gt; General &gt; Styles and Scripts, and making sure that &#8220;Enable WooCommerce lightbox on the product page&#8221; is checked:</p>
<div id="attachment_1626" class="wp-caption alignnone" style="width: 710px"><a href="http://www.skyverge.com/wp-content/uploads/2013/05/woocommerce-2-enable-lightbox.png"><img src="/wp-content/uploads/2013/05/woocommerce-2-enable-lightbox-700x216.png" alt="WooCommerce &gt; Settings &gt; General &gt; Styles and Scripts" width="700" height="216" class="size-medium wp-image-1626" /></a><p class="wp-caption-text">WooCommerce &gt; Settings &gt; General &gt; Styles and Scripts</p></div>
<h2 id="including-lightbox">Including Lightbox</h2>
<p>If you want to use the lightbox on, say, a product page, you&#8217;re in luck, with the above setting enabled, the lightbox styles/scripts will be automatically included.  If however you want to use the lightbox on a different part of your site, you will likely have to include those files with an action like the following:</p>
<pre class="brush: php; title: ; notranslate">
add_action( 'wp_enqueue_scripts', 'frontend_scripts_include_lightbox' );

function frontend_scripts_include_lightbox() {
  global $woocommerce;

  $suffix      = defined( 'SCRIPT_DEBUG' ) &amp;&amp; SCRIPT_DEBUG ? '' : '.min';
  $lightbox_en = get_option( 'woocommerce_enable_lightbox' ) == 'yes' ? true : false;

  if ( $lightbox_en ) {
    wp_enqueue_script( 'prettyPhoto', $woocommerce-&gt;plugin_url() . '/assets/js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true );
    wp_enqueue_script( 'prettyPhoto-init', $woocommerce-&gt;plugin_url() . '/assets/js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery' ), $woocommerce-&gt;version, true );
    wp_enqueue_style( 'woocommerce_prettyPhoto_css', $woocommerce-&gt;plugin_url() . '/assets/css/prettyPhoto.css' );
  }
}
</pre>
<p>This can be added to your theme&#8217;s <code>functions.php</code> in the usual manner (<code><em>theme-name</em>/functions.php</code>), or perhaps to your <a href="/articles/wordpress/creating-custom-plugin-for-your-woocommerce-shop/">custom site plugin</a>.  Note that this will have the effect of loading the lightbox script/style on <em>every</em> page of your site; if you want to limit it to certain pages/sections you can make use of the wide array of <a href="http://wcdocs.woothemes.com/codex/theming/conditional-tags/">conditional tags</a> available.</p>
<h2>Bring out the LIGHTBOX!</h2>
<p>Now that lightbox (really prettyphoto) is enabled and included, we can start using it.  If you just want to display one or more images in their own popup or little gallery, it&#8217;s as simple as wrapping them in an anchor tag and adding the &#8220;prettyPhoto&#8221; rel:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;a rel=&quot;prettyPhoto&quot; title=&quot;My Picture 1&quot; href=&quot;/path/to/image1.png&quot;&gt;&lt;img src=&quot;/path/to/image1.png&quot; /&gt;&lt;/a&gt;
&lt;a rel=&quot;prettyPhoto&quot; title=&quot;My Picture 2&quot; href=&quot;/path/to/image2.png&quot;&gt;&lt;img src=&quot;/path/to/image2.png&quot; /&gt;&lt;/a&gt;
</pre>
<div style="text-align:center;">
<a href="/wp-content/uploads/2012/08/flower1.jpg" rel="prettyPhoto[flowers]" title="Flower 1"><img src="/wp-content/uploads/2012/08/flower1-100x100.jpg" alt="" title="flower1" width="100" height="100" class="alignmiddle size-thumbnail wp-image-815" /></a><a href="/wp-content/uploads/2012/08/flower2.jpg" rel="prettyPhoto[flowers]" title="Flower 2"><img src="/wp-content/uploads/2012/08/flower2-100x100.jpg" alt="" title="flower2" width="100" height="100" class="alignmiddle size-thumbnail wp-image-816" /></a>
</div>
<h2 style="clear:left;">Advanced Usage</h2>
<p>If you need more control over the lightbox behavior, and/or wish to display content other than an image, you can make full use of the <a href="http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/documentation">api</a>.  You&#8217;ll just be responsible for injecting the relevant javascript into your page source, or including it in an external script, or whatever you prefer.</p>

<p>The post <a href="http://www.skyverge.com/blog/how-to-use-woocommerces-lightbox-part-2/">How to Use WooCommerce 2.0 Lightbox</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/how-to-use-woocommerces-lightbox-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Translating a WordPress Plugin on the Command Line Step by Step</title>
		<link>http://www.skyverge.com/blog/translating-a-wordpress-plugin-step-by-step/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=translating-a-wordpress-plugin-step-by-step</link>
		<comments>http://www.skyverge.com/blog/translating-a-wordpress-plugin-step-by-step/#comments</comments>
		<pubDate>Sat, 02 Mar 2013 00:11:25 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[localize]]></category>
		<category><![CDATA[translate]]></category>
		<category><![CDATA[wpml]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=900</guid>
		<description><![CDATA[<p>The purpose of this article is to provide a quick and easy to follow step-by-step guide to extracting text strings from a WordPress plugin for translation from the command line. Although this is documented in the codex: I18N for WordPress Developers and Translating WordPress, those articles are somewhat lengthy and the first time I was [...]</p><p>The post <a href="http://www.skyverge.com/blog/translating-a-wordpress-plugin-step-by-step/">Translating a WordPress Plugin on the Command Line Step by Step</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-901" title="wordpress-internationalization" alt="" src="/wp-content/uploads/2012/10/wordpress-internationalization.png" width="200" height="200" />The purpose of this article is to provide a quick and easy to follow step-by-step guide to extracting text strings from a WordPress plugin for translation from the command line. Although this is documented in the codex: <a href="http://codex.wordpress.org/I18n_for_WordPress_Developers">I18N for WordPress Developers</a> and <a href="http://codex.wordpress.org/Translating_WordPress">Translating WordPress</a>, those articles are somewhat lengthy and the first time I was asked to internationalize a plugin it took me some time to find the actual steps to generate my POT file.  The codex article might be better if you&#8217;re translating a plugin that you have listed on wordpress.org, but since the majority of my plugins are either custom for a client or myself, or listed in the WooThemes shop, I have to do my translation on the command line.</p>
<h2>Extracting Strings for Translation</h2>
<p>Although I won&#8217;t delve deeply into all aspects of WordPress internationalization (i18n), it is important to note that it&#8217;s built on the excellent GNU <a href="http://www.gnu.org/software/gettext/">gettext</a> localization framework. The basic process for translating a plugin or theme is as follows:</p>
<ol>
<li>Code the plugin/theme using the translation functions <code>__('message')</code>, <code>_e('message')</code>, etc. Include a call to <a href="http://codex.wordpress.org/Function_Reference/load_plugin_textdomain"><code>load_plugin_textdomain()</code></a> as I describe in my article <a href="/articles/wordpress/writing-plugin-localize-by-wpml/">Writing a Plugin That Can Be Localized by WPML</a>.</li>
<li>Extract all translatable strings into a POT file</li>
<li>Provide the POT file to a translator who returns one or more PO files with the text translated</li>
<li>Convert the PO file into an MO file</li>
<li>Place the MO file into the directory within your plugin that you specify in your call to <code>load_plugin_textdomain()</code>, ie &#8220;languages&#8221;</li>
</ol>
<h3>Step 1 &#8211; Coding</h3>
<p>While coding a plugin or theme it&#8217;s always good practice to use the special (and odd looking) localization functions whenever displaying text, with the two most common being: <code>__('message')</code> and <code>_e('message')</code>. Some additional useful functions to know include <a href="http://codex.wordpress.org/Function_Reference/_x"><code>_x('message', 'context')</code></a> which allows you to provide some context information for translators to provide them with additional comments needed to distinguish between the same word used in different contexts, for instance. Another one is <a href="http://codex.wordpress.org/Function_Reference/_n"><code>_n('message', 'plural', $number)</code></a> which is used to retrieve the singular or plural form of a string, based on the amount <code>$number</code>. There are a number of variations of these functions, as well as ones specialized for use with HTML attribute values for instance.</p>
<p>You should also use an appropriate text domain string based on your plugin name. If your plugin is called My-Plugin, your text domain might be &#8216;my-plugin&#8217; for instance.</p>
<h3>Step 2 &#8211; Extraction</h3>
<p>If you have not already done so, start by exporting the WordPress translation tools:</p>
<pre class="brush: bash; title: ; notranslate">$ svn export http://i18n.svn.wordpress.org/tools/trunk/</pre>
<p><em>Update 2013.03.01:</em> It looks like the current head (revision 21405) of the WordPress translation tools has a broken <code>makepot.php</code>.  When I tried to use it today the POT file it generated only contained strings from the main plugin file and none from the other plugin source files.  The previous revision does not have this bug, so until the issue is fixed I&#8217;d recommend exporting the tools like so:</p>
<pre class="brush: bash; title: ; notranslate">$ svn export -r 20807 http://i18n.svn.wordpress.org/tools/trunk/</pre>
<p>One of those scripts is <code>makepot.php</code> which is used like the following:</p>
<pre class="brush: bash; title: ; notranslate">$ php makepot.php wp-plugin /path/to/my-plugin</pre>
<p>Where <code>/path/to/my/plugin/</code> is the path to the plugin you wish to localize and will generate a POT file named like: <code>my-plugin.pot</code>. Rename it to match your text domain, and add the language suffix you want (or let your translator do this): ie <code>my-plugin-de_DE.pot</code>.</p>
<h3>Step 3 &#8211; Translate POT to PO</h3>
<p>Send your POT file to the translator, or translate it yourself if you have the knowledge. If you need to edit the PO file you&#8217;ll probably want to do so with a tool with UTF-8 support, depending on your target language. I had good luck with <a href="http://www.poedit.net/">Poedit</a> for this.</p>
<h3>Step 4 &#8211; Convert PO to MO</h3>
<p>Convert your PO file to the MO required by gettext by using the <code>msgfmt</code> utility:</p>
<pre class="brush: bash; title: ; notranslate">$ msgfmt -o my-plugin-de_DE.mo my-plugin-de_DE.po</pre>
<h3>Step 5 &#8211; Using the MO File</h3>
<p>Finally, drop your <code>my-plugin-de_DE.mo</code> into the directory within your plugin specified by your call to <code>load_plugin_textdomain()</code>.  So for instance, if you use the following:</p>
<pre class="brush: php; title: ; notranslate">load_plugin_textdomain( 'my-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );</pre>
<p>Then your <code>.mo</code> file would go in <code>my-plugin/languages/</code></p>
<h2>Testing</h2>
<p>Once you put your <code>mo</code> translation file into the plugin directory that you supplied in your call to <code>load_plugin_textdomain()</code> (as described in Step 5 above), you can test that your language file is being picked up by editing your sites <code>wp-config.php</code>.  There you should find a line like:  </p>
<pre class="brush: php; title: ; notranslate">define('WPLANG', '');</pre>
<p>Just change this to the language abbreviation, for instance:</p>
<pre class="brush: php; title: ; notranslate">define('WPLANG', 'de_DE');</pre>
<p>And visit your site to verify the translation is being picked up.</p>
<p>One possible stumbling point for developers: your translation files may not be picked up if you symlink your plugin into your webroot as I do.</p>
<p>Working with WPML, so that the site language isn&#8217;t hardcoded in your <code>wp-config.php</code> file and can for instance be selected by your site visitors, is a simple matter of making the <code>load_plugin_textdomain()</code> call in the correct place.  See my related article <a href="/articles/wordpress/writing-plugin-localize-by-wpml/">Writing a Plugin That Can Be Localized by WPML</a> for details.</p>
<h2>Updating Your Translation</h2>
<p>If you change text in your plugin and want to update your translation without re-translating everything, Poedit makes this a snap.  Simply:</p>
<ol>
<li>Follow the steps above to generate a new POT file with the current strings</li>
<li>Open your out of date PO file with Poedit</li>
<li>Go to Catalog &gt; Update from POT file&#8230; and choose your new POT file</li>
<li>Poedit will show you the obsolete and new strings.  You can choose to delete the obsolete strings, or leave them (they&#8217;ll be commented-out in your new PO file) and translate the new strings.</li>
<li>Save to generate the new PO/MO files</li>
</ol>
<h2>Bonus</h2>
<p>For a tip on supporting WPML see my article on <a href="/articles/wordpress/writing-plugin-localize-by-wpml/">Writing a Plugin That Can Be Localized by WPML</a>.</p>
<p>If you create new database tables for your plugin, ensure that the default charset is UTF8, otherwise accented and other special characters that get inserted into them will not render properly:</p>
<pre class="brush: sql; title: ; notranslate">CREATE TABLE blah ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
<p><small><em>WordPress Globe Icon image credit: <a href="http://adminsuperwoman.com/wordpress-websites/globe-icon-wordpress/">http://adminsuperwoman.com/wordpress-websites/globe-icon-wordpress/</a></em></small></p>
<p>The post <a href="http://www.skyverge.com/blog/translating-a-wordpress-plugin-step-by-step/">Translating a WordPress Plugin on the Command Line Step by Step</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/translating-a-wordpress-plugin-step-by-step/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Add Custom Options to WooCommerce Settings</title>
		<link>http://www.skyverge.com/blog/add-custom-options-to-woocommerce-settings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=add-custom-options-to-woocommerce-settings</link>
		<comments>http://www.skyverge.com/blog/add-custom-options-to-woocommerce-settings/#comments</comments>
		<pubDate>Tue, 19 Feb 2013 17:17:12 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[woocommerce]]></category>
		<category><![CDATA[woocommerce admin]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1265</guid>
		<description><![CDATA[<p>This question comes in from blog reader Wilgert (thanks Wilgert!): could you help me find some simple code to add a custom option field to the general settings tab of the woocommerce admin area? Trying to avoid re-inventing the wheel here. Well, this may be more than you bargained for, but here we go! The [...]</p><p>The post <a href="http://www.skyverge.com/blog/add-custom-options-to-woocommerce-settings/">Add Custom Options to WooCommerce Settings</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2012/03/woocommerce_logo_leader.png" alt="WooCommerce" width="588" height="130" class="alignnone size-full wp-image-412" /></p>
<p>This question comes in from blog reader Wilgert (thanks Wilgert!):</p>
<blockquote><p>could you help me find some simple code to add a custom option field to the general settings tab of the woocommerce admin area? Trying to avoid re-inventing the wheel here.</p></blockquote>
<p>Well, this may be more than you bargained for, but here we go!  The WooCommerce settings can be found under the menu item WooCommerce &gt; Settings and look like so:</p>
<p><img src="/wp-content/uploads/2013/02/woocommerce-settings-general-588x147.png" alt="WooCommerce Settings General" width="588" height="147" class="alignnone size-large wp-image-1267" /></p>
<p>Like a lot of WooCommerce these settings can be customized thanks to a variety of actions and filters.  For the main settings tabs there are 7 important filters to consider:</p>
<ul id="woocommerce-settings-filters">
<li><code>woocommerce_general_settings</code></li>
<li><code>woocommerce_catalog_settings</code></li>
<li><code>woocommerce_page_settings</code></li>
<li><code>woocommerce_inventory_settings</code></li>
<li><code>woocommerce_tax_settings</code></li>
<li><code>woocommerce_shipping_settings</code></li>
<li><code>woocommerce_payment_gateways_settings</code></li>
<li><code>woocommerce_email_settings</code></li>
</ul>
<p>As you can see, one for each of the major tabs, excluding the final &#8220;Integration&#8221; tab, which is handled elsewhere.</p>
<p>Each of those filters accepts and returns the same nested array data structure, which describes the options and headings shown on the Settings tabs, allowing you easily modify, remove and even add your own custom settings (and even whole new sections of settings).  Here&#8217;s an example snippet showing some of the common types of settings fields: a dropdown, a text input and a checkbox:</p>
<pre>

array(

  array(

    'name' => __( 'Pricing Options', 'woocommerce' ),

    'type' => 'title',

    'desc' => __('The following options affect how prices are displayed on the frontend.', 'woocommerce'),

    'id' => 'pricing_options'

  ),



  array(

    'name'    => __( 'Currency Position', 'woocommerce' ),

    'desc'    => __( 'This controls the position of the currency symbol.', 'woocommerce' ),

    'id'      => 'woocommerce_currency_pos',

    'css'     => 'min-width:150px;',

    'std'     => 'left', // WooCommerce < 2.0

    'default' => 'left', // WooCommerce >= 2.0

    'type'    => 'select',

    'options' => array(

      'left'        => __( 'Left', 'woocommerce' ),

      'right'       => __( 'Right', 'woocommerce' ),

      'left_space'  => __( 'Left (with space)', 'woocommerce' ),

      'right_space' => __( 'Right (with space)', 'woocommerce' )

    ),

    'desc_tip' =>  true,

  ),



  array(

    'name'     => __( 'Thousand separator', 'woocommerce' ),

    'desc'     => __( 'This sets the thousand separator of displayed prices.', 'woocommerce' ),

    'id'       => 'woocommerce_price_thousand_sep',

    'css'      => 'width:30px;',

    'std'      => ',', // WooCommerce < 2.0

    'default'  => ',', // WooCommerce >= 2.0

    'type'     => 'text',

    'desc_tip' =>  true,

  ),



  array(

    'name'    => __( 'Trailing zeros', 'woocommerce' ),

    'desc'    => __( 'Remove zeros after the decimal point. e.g. <code>$10.00</code> becomes <code>$10</code>', 'woocommerce' ),

    'id'      => 'woocommerce_price_trim_zeros',

    'std'     => 'yes', // WooCommerce < 2.0

    'default' => 'yes', // WooCommerce >= 2.0

    'type'    => 'checkbox'

  ),



  array( 'type' => 'sectionend', 'id' => 'pricing_options' ),

);

</pre>
<p>Which will render roughly like:</p>
<p><img src="/wp-content/uploads/2013/02/woocommerce-settings-pricing-options-588x170.png" alt="WooCommerce Settings Pricing Options" width="588" height="170" class="alignnone size-large wp-image-1274" /></p>
<p>By inspecting the settings data structure we see that it consists of an array of arrays, where each child array represents an element (heading, field or section end) on the settings page.  A section of settings starts with an array with a type &#8216;title&#8217;, containing a &#8216;name&#8217;, &#8216;desc&#8217; description and unique &#8216;id&#8217;.  Any subsequent arrays are part of that section until we hit a special array with type &#8216;sectionend&#8217; and an &#8216;id&#8217; matching that of the starting section element.</p>
<p>The individual settings fields are given as arrays with a number of common arguments, along with some optional ones depending on the field &#8216;type&#8217;:</p>
<dl>
<dt>type</dt>
<dd>(string) Required field type with some common options: &#8216;text&#8217;, &#8216;color&#8217;, &#8216;image_width&#8217;, &#8216;select&#8217;, &#8216;checkbox&#8217;, &#8216;textarea&#8217;.  Also some special case options: &#8216;single_select_page&#8217;, &#8216;single_select_country&#8217;, &#8216;multi_select_countries&#8217;.  And you can even define your own custom type, providing the implementation via the <code>woocommerce_admin_field_{mytype}</code> action.</dd>
<dd><strong>Note:</strong> WooCommerce 2.0 introduces some new types: &#8216;email&#8217;, &#8216;pasword&#8217;, &#8216;number&#8217;, &#8216;multiselect&#8217; and &#8216;radio&#8217;.</dd>
<dt>name</dt>
<dd>(string) The displayed field name</dd>
<dd><strong>Note:</strong> In WooCommerce 2.0 &#8216;name&#8217; is replaced by a new field &#8216;title&#8217;, however the new &#8216;title&#8217; field defaults to &#8216;name&#8217;, so for now at least you&#8217;re safe using &#8216;name&#8217; and compatible with both WC 1.6.6 and previous as well as WC 2.0+</dd>
<dt>title</dt>
<dd>(string) <strong>WooCommerce 2.0 only</strong> This replaces the &#8216;name&#8217; field in WooCommerce 2.0+, but defaults to &#8216;name&#8217; if that field is provided.</dd>
<dt>id</dt>
<dd>(string) Unique field identifier, used to retrieve the field from the database options table</dd>
<dt>class</dt>
<dd>(string) Optional field class names</dd>
<dt>css</dt>
<dd>(string) Optional field custom css</dd>
<dt>std</dt>
<dd>(mixed) Optional field default value if the field type is &#8216;text&#8217;, &#8216;color&#8217;, &#8216;image_width&#8217;, &#8216;select&#8217; or &#8216;textarea&#8217;.  This can be a string, numeric or array depending on the option field &#8216;type&#8217;</dd>
<dd><strong>Removed in upcoming WooCommerce 2.0</strong></dd>
<dt>default</dt>
<dd>(mixed) Field default value.  This can be a string, numeric or array depending on the option field &#8216;type&#8217;</dd>
<dd><strong>This more appropriately named argument is available only for WooCommerce 2.0 and is available for all field types.  For now just use both &#8216;std&#8217; and &#8216;default&#8217; with the same value</strong></dd>
<dt>desc</dt>
<dd>(string) Optional field description, displayed next to the input element, or used as the tooltip, depending on &#8216;desc_tip&#8217;</dd>
<dt>desc_tip</dt>
<dd>(boolean|string) If <code>true</code> and &#8216;desc&#8217; is provided, &#8216;desc&#8217; will be used as the field tool tip.  If a string is used it will be set as the tool tip.</dd>
<dd><strong>Note:</strong> With WooCommerce 2.0+ you can have both a description and tooltip by using strings for each.</dd>
<dt>options</dt>
<dd>(array) Associative array of option name to value, this is used for the &#8216;select&#8217;, &#8216;multiselect&#8217; or &#8216;radio&#8217; field types</dd>
<dt>checkboxgroup</dt>
<dd>(string) Optional for fields of type &#8216;checkbox&#8217;, value can be one of &#8216;start&#8217;, &#8221; or &#8216;end&#8217;.  This is used to create a grouping of checkboxes under a single title/name, and for purposes of showing/hiding some checkboxes based on whether another is checked or not.  This allows you to create options that are only visible if another option is checked or not checked.</dd>
<dt>show_if_checked</dt>
<dd>(string) Show a checkbox if another is checked.  Optional for fields of type &#8216;checkbox&#8217; that are part of a &#8216;checkboxgroup&#8217;, value can be one of &#8216;option&#8217;, &#8216;yes&#8217; or &#8216;no&#8217; (default).  Only one checkbox in a checkboxgroup should be marked as &#8216;option&#8217;: this is the checkbox that controls the visibility of the others which have a value of &#8216;yes&#8217;.</dd>
<dt>hide_if_checked</dt>
<dd>(string) Hide a checkbox if another is checked.  Optional for fields of type &#8216;checkbox&#8217; that are part of a &#8216;checkboxgroup&#8217;, value can be one of &#8216;option&#8217;, &#8216;yes&#8217; or &#8216;no&#8217; (default).  Only one checkbox in a checkboxgroup should be marked as &#8216;option&#8217;: this is the checkbox that controls the visibility of the others which have a value of &#8216;yes&#8217;.</dd>
</dl>
<p>I know there are a lot of possible arguments, with all different values which can be confusing and compounded by the changes with upcoming WooCommerce 2.0, but if you ever have any doubts about how something works, or what options you have, take a look at the <code>woocommerce_admin_fields()</code> function found in <code>woocommerce/admin/woocommerce-admin-settings.php</code>.  Also the full set of WooCommerce settings can be found in the <code>woocommerce/admin/settings/settings-init.php</code> file and is a great starting point to find an example close to what you want to do.</p>
<p>Remember that if the above standard fields don&#8217;t do quite what you&#8217;re looking for you can always define your own totally custom option type along with whatever custom arguments you want, by hooking into the <code>woocommerce_admin_field_{mytype}</code> action.</p>
<p>Any setting field value can be retrieved from the database by using the standard WordPress <code><a href="http://codex.wordpress.org/Function_Reference/get_option">get_option()</a></code> function with the option&#8217;s &#8216;id&#8217;.  Ie:</p>
<pre>

$woocommerce_price_trim_zeros = get_option( 'woocommerce_price_trim_zeros' );

</pre>
<h2>Example</h2>
<p>Now with all the formalities and background taken care of, how do we actually add a custom setting option you ask?  It&#8217;s a simple matter of hooking onto the particular <a href="#woocommerce-settings-filters">settings filter</a> depending on what tab you want, and adding the option in at the appropriate place in the settings array.  Here&#8217;s some code from my <a href="http://www.woothemes.com/products/sequential-order-numbers-pro/">Sequential Order Numbers Pro</a> plugin which adds a text option named &#8220;Order Number Start&#8221; to the &#8220;General&#8221; tab before the end of the &#8220;General Options&#8221; section:</p>
<pre>

add_filter( 'woocommerce_general_settings', 'add_order_number_start_setting' );



function add_order_number_start_setting( $settings ) {



  $updated_settings = array();



  foreach ( $settings as $section ) {



    // at the bottom of the General Options section

    if ( isset( $section['id'] ) &#038;&#038; 'general_options' == $section['id'] &#038;&#038;

       isset( $section['type'] ) &#038;&#038; 'sectionend' == $section['type'] ) {



      $updated_settings[] = array(

        'name'     => __( 'Order Number Start', 'wc_seq_order_numbers' ),

        'desc_tip' => __( 'The starting number for the incrementing portion of the order numbers, unless there is an existing order with a higher number.', 'wc_seq_order_numbers' ),

        'id'       => 'woocommerce_order_number_start',

        'type'     => 'text',

        'css'      => 'min-width:300px;',

        'std'      => '1',  // WC < 2.0

        'default'  => '1',  // WC >= 2.0

        'desc'     => __( 'Sample order number: AA-20130219-000-ZZ', 'wc_seq_order_numbers' ),

      );

    }



    $updated_settings[] = $section;

  }

  return $updated_settings;

}

</pre>
<p>Which will look like:</p>
<p><img src="/wp-content/uploads/2013/02/woocommerce-settings-custom-option-588x211.png" alt="WooCommerce Settings Custom Option" width="588" height="211" class="alignnone size-large wp-image-1293" /></p>
<p>Your custom option setting will be automatically saved to the database to the standard WordPress options table with the field &#8216;id&#8217; as the option name.  Retrieve it using the standard WordPress <code><a href="http://codex.wordpress.org/Function_Reference/get_option">get_option()</a></code> function.  Just don&#8217;t forget that if you use a default value for your setting that you&#8217;ll have to either set that value with an &#8220;install&#8221; function, or use it as the second parameter when retrieving your option from the database.  For instance:</p>
<pre>

$order_number_start = get_option( 'woocommerce_order_number_start', 1 );

</pre>
<p>The post <a href="http://www.skyverge.com/blog/add-custom-options-to-woocommerce-settings/">Add Custom Options to WooCommerce Settings</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/add-custom-options-to-woocommerce-settings/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Set a Default Stock Quantity for WooCommerce Products</title>
		<link>http://www.skyverge.com/blog/set-default-stock-quantity-woocommerce-variations/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=set-default-stock-quantity-woocommerce-variations</link>
		<comments>http://www.skyverge.com/blog/set-default-stock-quantity-woocommerce-variations/#comments</comments>
		<pubDate>Sun, 17 Feb 2013 15:31:38 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[woocommerce]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1112</guid>
		<description><![CDATA[<p>Here's a quick little snippet that you can make use of if you want to set a default stock quantity for any newly added WooCommerce product Variations.  This can be useful when bulk-adding variations and you don't want an initial quantity of ''.</p><p>The post <a href="http://www.skyverge.com/blog/set-default-stock-quantity-woocommerce-variations/">Set a Default Stock Quantity for WooCommerce Products</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2012/03/woocommerce_logo_leader.png" alt="WooCommerce" width="588" height="130" class="alignnone size-full wp-image-412" /></p>
<p>Here&#8217;s a quick little snippet that you can make use of if you want to set a default stock quantity for any newly added WooCommerce product Variations.  This can be useful when bulk-adding variations and you don&#8217;t want an initial quantity of &#8221;.</p>
<pre class="brush: php; title: ; notranslate">
add_action( 'admin_enqueue_scripts', 'wc_default_variation_stock_quantity' );

function wc_default_variation_stock_quantity() {
  global $pagenow, $woocommerce;

  $default_stock_quantity = 0;
  $screen = get_current_screen();

  if ( ( $pagenow == 'post-new.php' || $pagenow == 'post.php' || $pagenow == 'edit.php' ) &amp;&amp; $screen-&gt;post_type == 'product' ) {

    ob_start();
    ?&gt;
    $('.woocommerce_variations').bind('woocommerce_variations_added',function() {
      $('.woocommerce_variations input').each(function(index,el) {
        el = $(el);
        if(el.attr('name') &amp;&amp; el.attr('name').substr(0,14) == 'variable_stock' &amp;&amp; el.val() == '') {
          el.val(&lt;?php echo $default_stock_quantity; ?&gt;);
        }
      });
    });
    &lt;?php
    $javascript = ob_get_clean();
    $woocommerce-&gt;add_inline_js( $javascript );
  }
}
</pre>
<p>Or, if you need a default stock quantity for simple products:</p>
<pre class="brush: php; title: ; notranslate">
add_action( 'admin_enqueue_scripts', 'wc_default_variation_stock_quantity' );

function wc_default_variation_stock_quantity() {
  global $pagenow, $woocommerce;

  $default_stock_quantity = 0;
  $screen = get_current_screen();

  if ( ( $pagenow == 'post-new.php' || $pagenow == 'post.php' || $pagenow == 'edit.php' ) &amp;&amp; $screen-&gt;post_type == 'product' ) {

    ob_start();
    ?&gt;
    if ( '' === $( '#_stock' ).val() ) {
      $( '#_stock' ).val(&lt;?php echo $default_stock_quantity; ?&gt;);
    }
    &lt;?php
    $javascript = ob_get_clean();
    $woocommerce-&gt;add_inline_js( $javascript );
  }
}
</pre>
<p>The post <a href="http://www.skyverge.com/blog/set-default-stock-quantity-woocommerce-variations/">Set a Default Stock Quantity for WooCommerce Products</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/set-default-stock-quantity-woocommerce-variations/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress Get DB Table Column Names</title>
		<link>http://www.skyverge.com/blog/get-table-column-names/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-table-column-names</link>
		<comments>http://www.skyverge.com/blog/get-table-column-names/#comments</comments>
		<pubDate>Mon, 14 Jan 2013 23:33:02 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1097</guid>
		<description><![CDATA[<p>To get the column names for a MySQL database table in WordPress, use the following: global $wpdb; $table_name = $wpdb->prefix . 'posts'; foreach ( $wpdb->get_col( "DESC " . $table_name, 0 ) as $column_name ) { error_log( $column_name ); } Which will result in something like the following being printed to your debug.log: ID post_author post_date [...]</p><p>The post <a href="http://www.skyverge.com/blog/get-table-column-names/">WordPress Get DB Table Column Names</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2013/01/wordpress-db-header-588x98.png" alt="wordpress-db-header" width="588" height="98" class="alignnone size-large wp-image-1103" /></p>
<p>To get the column names for a MySQL database table in WordPress, use the following:</p>
<pre>

global $wpdb;



$table_name = $wpdb->prefix . 'posts';

foreach ( $wpdb->get_col( "DESC " . $table_name, 0 ) as $column_name ) {

  error_log( $column_name );

}

</pre>
<p>Which will result in something like the following being printed to your debug.log:</p>
<pre>

ID

post_author

post_date

post_date_gmt

post_content

...

</pre>
<p>You get the idea</p>
<p>The post <a href="http://www.skyverge.com/blog/get-table-column-names/">WordPress Get DB Table Column Names</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/get-table-column-names/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guide to Migrating Your Plugin to WooCommerce 2.0</title>
		<link>http://www.skyverge.com/blog/migrating-your-plugin-woocommerce-2-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrating-your-plugin-woocommerce-2-0</link>
		<comments>http://www.skyverge.com/blog/migrating-your-plugin-woocommerce-2-0/#comments</comments>
		<pubDate>Mon, 14 Jan 2013 06:15:00 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[woocommerce]]></category>
		<category><![CDATA[woocommerce 2.0]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1084</guid>
		<description><![CDATA[<p>With the release of WooCommerce 2.0 becoming more imminent (well, maybe not quite imminent yet, but certainly drawing nearer), those of us with WooCommerce plugins need to start work on getting them ready for the big release. WooCommerce has never been one to hold back on making plugin-busting implementation changes with a new release, and [...]</p><p>The post <a href="http://www.skyverge.com/blog/migrating-your-plugin-woocommerce-2-0/">Guide to Migrating Your Plugin to WooCommerce 2.0</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.woothemes.com/2013/01/woocommerce-2-0-beta-2-is-here/"><img src="/wp-content/uploads/2013/01/wc2b2-588x153.jpg" alt="WooCommerce 2.0 Beta 3" width="588" height="153" class="aligncenter size-large wp-image-1086" /></a></p>
<p>With the release of WooCommerce 2.0 becoming more imminent (well, maybe not quite imminent yet, but certainly drawing nearer), those of us with WooCommerce plugins need to start work on getting them ready for the big release.  WooCommerce has never been one to hold back on making plugin-busting implementation changes with a new release, and they&#8217;re setting the bar quite high with 2.0.  It&#8217;s chalk full of code changes and improvements plugin developers must be aware of and potential handle, and I&#8217;ve personally spent many hours already preparing my various WooThemes-listed plugins for WC 2.0, with yet more work ahead of me I&#8217;m sure.  I figure with all the time I&#8217;ve already spent researching this stuff, there&#8217;s no need for <em>you</em> to have to do the same, and so I&#8217;m putting together this guide on migrating existing plugins to WooCommerce 2.0, which I plan to continue to update as I find new issues/fixes, and I hope you dear reader will do the same in the comment section below!</p>
<p>The intended audience for the guide would most likely be developers with custom plugins for clients which they want to get updated ahead of time, or at least be ready to update once 2.0 is released.  I&#8217;d imagine other developers in the WooCommerce developers program will be aware of most of this already.  The majority of the fixes and approaches I describe in this article are from actual code snippets that I&#8217;ve used to update my own WooThemes-listed plugins, and hence they are written to be both backwards-compatible with the current WooCommerce 1.6.6, and compatible with the upcoming WooCommerce 2.0.  It also means that they cover only those issues I&#8217;ve encountered with my own plugins, and thus couldn&#8217;t hope to cover all potential issues.  If you&#8217;re responsible for a custom plugin for a client or small number of clients and have more control over the environment in which they run, you can certainly simplify your plugin by targeting it solely for 2.0; though for the most part it&#8217;s not a whole lot more effort to be backwards compatible as well.</p>
<p>As always, I make no claims or guarantees about the correctness or efficacy of the code shown below, and if you use it you do so at your own risk.  I won&#8217;t be held responsible if something blows up!  WooCommerce 2.0 is also still very much a work in progress and a moving target, but I believe the fixes I&#8217;ve already come up with should hold as they come to a final release candidate.</p>
<h2>Testing</h2>
<p>The first and most important step is to test your plugin with the latest beta of WooCommerce, at time of writing called <a href="https://github.com/woothemes/woocommerce/tree/v2.0.0-beta3">WooCommerce 2.0.0-beta3</a>.  Or, if you&#8217;re feeling lucky, just use the current head of the WooCommerce repository.  With any luck your plugin will work just fine and your job will be done before it&#8217;s begun.  Crack open a beer! (but don&#8217;t forget to continue testing with each beta and especially the final release)</p>
<h2>Overview</h2>
<p>If you&#8217;re still with me, then perhaps some part of your plugin is broken by the 2.0 beta.  Well, you&#8217;re in good company.  We&#8217;ll start with a listing of potential issues and then delve into them one-by-one:</p>
<ol>
<li><a href="#products">Products</a></li>
<li><a href="#sessions">Sessions</a></li>
<li><a href="#order_item_data">Order Item Data</a></li>
<li><a href="#payment_gateways">Payment Gateways</a></li>
<li><a href="#odds_and_ends">Odds and Ends</a></li>
</ol>
<h2>Additional Resources</h2>
<p>Also see the WooThemes article <a href="http://wcdocs.woothemes.com/version-notes/woocommerce-1-6-6-2-0-plugin-and-theme-compatibility/">WooCommerce 1.6.6 -&gt; 2.0 – Plugin and theme compatibility</a>, which identifies some of the same issues/approaches I outline below, as well as some things I didn&#8217;t cover, especially with regards to themes.</p>
<h2 id="products">Products</h2>
<p>The first and most likely spot of trouble is with the product class.</p>
<h3>Instantiating WC_Product</h3>
<p>Products have received quite an overhaul in WooCommerce 2.0, and if you ever did <code>new WC_Product()</code> in your code you&#8217;re going to have to make a few changes.  With 2.0 the <code>WC_Product</code> class is made abstract, meaning that to try and instantiate it is to be hit with a Fatal Error.  The fix is to use the new product factory class to retrieve a new product instance, which you can do in a forwards/backwards compatible manner like so:</p>
<pre>

/**

 * Gets the identified product. Compatible with WC 2.0 and backwards

 * compatible with previous versions

 *

 * @param int $product_id the product identifier

 * @param array $args optional array of arguments

 *

 * @return WC_Product the product

 */

function my_plugin_get_product( $product_id, $args = array() ) {

  $product = null;



  if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {

    // WC 2.0

    $product = get_product( $product_id, $args );

  } else {



    // old style, get the product or product variation object

    if ( isset( $args['parent_id'] ) &#038;&#038; $args['parent_id'] ) {

      $product = new WC_Product_Variation( $product_id, $args['parent_id'] );

    } else {

      // get the regular product, but if it has a parent, return the product variation object

      $product = new WC_Product( $product_id );

      if ( $product->get_parent() ) {

        $product = new WC_Product_Variation( $product->id, $product->get_parent() );

      }

    }

  }



  return $product;

}

</pre>
<p>As you can see, we check for the current version of WooCommerce:  if running under 2.0 or greater, we use the spiffy new <code>get_product()</code> function, otherwise we create a product or product variation as normal.  This can be used as simply as:</p>
<pre>

$product = my_plugin_get_product( 15 );

</pre>
<h3>Product Custom Meta Fields</h3>
<p>The next product change we need to concern ourselves with is the handling of custom meta fields.  Gone is the old <code>product_custom_fields</code> array (except for product variations!) from which all product <code>wp_postmeta</code> fields were available.  In its place is the PHP magic method <code><a href="http://php.net/manual/en/language.oop5.overloading.php#object.get">__get</a></code>.  This means that instead of say <code>$product->product_custom_fields['_my_field'][0]</code> we simply do: <code>$product->my_field</code>.  Cool!  Still, you have to make sure and make the change, and at least as of beta2 make sure you handle product variations correctly if you have a custom meta that you allow to be set in the parent product and potentially overridden in the child.  Here&#8217;s a helper function to help you along if you want to support WC 1.6 as well as the new 2.0:</p>
<pre>

/**

 * Helper function to retrieve a custom field from a product, compatible

 * both with WC < 2.0 and WC >= 2.0

 *

 * @param WC_Product $product the product object

 * @param string $field_name the field name, without a leading underscore

 *

 * @return mixed the value of the member named $field_name, or null

 */

function my_plugin_get_product_meta( $product, $field_name ) {

  if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {

    // even in WC >= 2.0 product variations still use the product_custom_fields array apparently

    if ( $product->variation_id &#038;&#038; isset( $product->product_custom_fields[ '_' . $field_name ][0] ) &#038;&#038; $product->product_custom_fields[ '_' . $field_name ][0] !== '' ) {

      return $product->product_custom_fields[ '_' . $field_name ][0];

    }

    // use magic __get

    return maybe_unserialize( $product->$field_name );

  } else {

    // use product custom fields array



    // variation support: return the value if it's defined at the variation level

    if ( isset( $product->variation_id ) &#038;&#038; $product->variation_id ) {

      if ( ( $value = get_post_meta( $product->variation_id, '_' . $field_name, true ) ) !== '' ) return $value;

      // otherwise return the value from the parent

      return get_post_meta( $product->id, '_' . $field_name, true );

    }



    // regular product

    return isset( $product->product_custom_fields[ '_' . $field_name ][0] ) ? $product->product_custom_fields[ '_' . $field_name ][0] : null;

  }

}

</pre>
<p>As you can see, regardless of the version, if <code>$product</code> is a variation, that variation is checked first, followed by its parent.  You use this method in the following way:</p>
<pre>

$value = my_plugin_get_product_meta( $product, 'my_field' );

</pre>
<p>Perhaps not as snazzy as <code>$product->my_field</code>, but if you want/need that 1.6 compatibility, that&#8217;s the tradeoff.</p>
<p>There are a slew of other product changes of course, but nothing that&#8217;s given me problems in the plugins I&#8217;ve tested thus far.</p>
<h2 id="sessions">Sessions</h2>
<p>Next on the list is sessions.  WooCommerce 2.0 no longer uses the PHP <a href="http://php.net/manual/en/function.session-start.php">session_start</a> function, instead it makes use of WordPress&#8217; transients, which is great, unless your code happens to rely on <code>$_SESSION</code>.  Of course one of my plugins did, so here&#8217;s a couple of functions to ease your migration to 2.0 and still support any 1.6 installs out there:</p>
<pre>

/**

 * Safely store data into the session. Compatible with WC 2.0 and

 * backwards compatible with previous versions.

 *

 * @param string $name the name

 * @param mixed $value the value to set

 */

private function my_plugin_session_set( $name, $value ) {

  global $woocommerce;



  if ( isset( $woocommerce->session ) ) {

    // WC 2.0

    $woocommerce->session->$name = $value;

  } else {

    // old style

    $_SESSION[ $name ] = $value;

  }

}



/**

 * Safely retrieve data from the session. Compatible with WC 2.0 and

 * backwards compatible with previous versions.

 *

 * @param string $name the name

 * @return mixed the data, or null

 */

function my_plugin_session_get( $name ) {

  global $woocommerce;



  if ( isset( $woocommerce->session ) ) {

    // WC 2.0

    if ( isset( $woocommerce->session->$name ) ) return $woocommerce->session->$name;

  } else {

    // old style

    if ( isset( $_SESSION[ $name ] ) ) return $_SESSION[ $name ];

  }

}



/**

 * Safely remove data from the session. Compatible with WC 2.0 and

 * backwards compatible with previous versions.

 *

 * @param string $name the name

 */

function my_plugin_session_delete( $name ) {

  global $woocommerce;



  if ( isset( $woocommerce->session ) ) {

    // WC 2.0

    unset( $woocommerce->session->$name );

  } else {

    // old style

    unset( $_SESSION[ $name ] );

  }

}

</pre>
<p>Hopefully you&#8217;ll agree these are simple enough that they don&#8217;t require a lengthy explanation or usage example.</p>
<h2 id="order_item_data">Order Item Data</h2>
<p>Order Item Data is no longer stored directly in the <code>wp_postmeta</code> table as meta attached to the order post row and serialized in an array, which is actually great news and should make for much more efficient and larger possible stores.  Order items and item data are now stored in <code>wp_woocommerce_order_items</code> and <code>wp_woocommerce_order_itemmeta</code> respectively.  Order items and item meta data can be added using the new functions <code>woocommerce_add_order_item()</code> and <code>woocommerce_add_order_item_meta()</code>:</p>
<pre>

$item_id = woocommerce_add_order_item( $order_id, array(

  'order_item_name' => 'Product Title',

  'order_item_type' => 'line_item'

) );

woocommerce_add_order_item_meta( $item_id, 'my_item_meta', 'my_item_meta_value' );

</pre>
<p>There&#8217;s other new functions to delete items and meta, and update, etc.  Also if you need to write custom queries against order items or item meta this will be much more efficient/possible now.</p>
<p>If you used the <code>WC_Order_Item_Meta</code> class previously, there have been a couple of changes therein:</p>
<ol>
<li><code>WC_Order_Item_Meta::add()</code> is gone</li>
<li>As is <code>WC_Order_Item_Meta::new_order_item()</code></li>
<li>The internal meta storage has changed to key-value pairs, rather than pairs of &#8216;meta_key&#8217; and &#8216;meta_value&#8217;.  (take a look at the class if you use this, it&#8217;ll make sense)</li>
</ol>
<p>Finally, of interest if you&#8217;re in the business of adding custom item meta to the cart (say with custom configurable products on the frontend) the <code>woocommerce_order_item_meta</code> action is gone, and in its place we have:  <code>woocommerce_add_order_item_meta</code>.  You can support both actions to get backwards/forwards compatibility:</p>
<pre>

add_action( 'woocommerce_order_item_meta', 'my_plugin_order_item_meta', 10, 2 ); // WC < 2.0

add_action( 'woocommerce_add_order_item_meta', 'my_plugin_add_order_item_meta', 10, 2 ); // WC >= 2.0

</pre>
<p>The implementations of <code>my_plugin_order_item_meta()</code> and <code>my_plugin_add_order_item_meta()</code> will probably be largely similar, you&#8217;ll just want to use the new <code>woocommerce_add_order_item_meta()</code> function mentioned above in the WC 2.0 version.</p>
<h3>Deprecated <code>order_item_meta</code> Class is Gone</h3>
<p>The deprecated <code>order_item_meta</code> class is now removed, so if you&#8217;re still using that class in your code, make sure to replace it with <code>WC_Order_Item_Meta</code> otherwise you&#8217;ll get a fatal error.</p>
<h2 id="payment_gateways">Payment Gateways</h2>
<p>Don&#8217;t know how many of you out there will have payment gateways you&#8217;ll be needing to update, but just in case, there have been a few changes to be aware of.</p>
<h3>Smart Loading</h3>
<p>Payment gateways in WC 2.0 have gotten a treatment similar to what Shipping Methods received in WooCommerce 1.5.7.  The big change is that rather than being instantiated on every request, they are now loaded only when needed.  This one change is supposedly responsible for quite a saving of resources and server performance.  Which is all well and good, unless of course your payment gateway actually <strong>needs</strong> to take some actions anywhere other than the admin settings page, checkout/pay pages, and API call.  The solution I&#8217;ve used and developed alongside fellow WC developer <a href="http://www.maxrice.com/">Max Rice</a> is to create a lightweight &#8220;main&#8221; class which is always instantiated and which manages and registers the payment gateway class responsible for communicating with the gateway, and registers any actions or filters where the payment gateway class might be needed.</p>
<p>No real applicable code samples or examples here, however those of you with redirect gateways, or any gateways that registers a WooCommerce API hook, you&#8217;ll need to ensure that the action you register contains the gateway class name.  Here&#8217;s a sample API hook added from within a payment gateway class:</p>
<pre>

add_action( 'woocommerce_api_' . strtolower( get_class( $this ) ), array( $this, 'gateway_response' ) );

</pre>
<p>Without this your gateway will <strong>not</strong> not be created and will not be called to handle that API request.  Of course you can use the same &#8220;main&#8221; class pattern described above to register any arbitrary API request handler you may require, and indeed I have to do this with two of my own gateways.</p>
<h3>Saving Settings</h3>
<p>The other gateway change is much simpler, there&#8217;s a new action required to save the gateway settings.  You can easily support both WC 1.6 and 2.0+ by just adding the new hook alongside the existing:</p>
<pre>

if ( is_admin() ) {

  add_action( 'woocommerce_update_options_payment_gateways',              array( $this, 'process_admin_options' ) );  // WC < 2.0

  add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );  // WC >= 2.0

}

</pre>
<h2 id="odds_and_ends">Odds and Ends</h2>
<p>And then there&#8217;s all the little odds and ends we&#8217;ve run in to.</p>
<h3>Admin Help Tip Image Elements</h3>
<p>The Help Tip image has changed, so be sure to add a width/height of 16 otherwise it will look funky and large:</p>
<pre>

<img class="help_tip" width="16" height="16" ...

</pre>
<h3>Media Browser</h3>
<p>Although not strictly related to WooCommerce 2.0 it's recommended and a good practice to <a href="http://mikejolley.com/2012/12/using-the-new-wordpress-3-5-media-uploader-in-plugins/">use the new WordPress 3.5 media browser</a>.</p>
<h3>Admin Product Data Tab CSS</h3>
<p>The product data tabs have changed from a horizontal layout in 1.6:</p>
<p><img src="/wp-content/uploads/2013/01/product-data-tabs-horizontal-588x163.png" alt="product-data-tabs-horizontal" width="588" height="163" class="aligncenter size-large wp-image-1087" /></p>
<p>To a much more efficient vertical layout in 2.0:</p>
<p><img src="/wp-content/uploads/2013/01/product-data-tabs-vertical-588x192.png" alt="product-data-tabs-vertical" width="588" height="192" class="aligncenter size-large wp-image-1088" /></p>
<p>Requiring some annoying CSS changes if you want to have your tabs looking correct in both 1.6 and 2.0+.  Here's the best Max and I have come up with:</p>
<pre>

add_action( 'woocommerce_product_write_panel_tabs', 'my_plugin_product_tabs_panel_tab' );



/**

 * Adds the "Tabs" tab to the Product Data postbox in the admin product interface

 */

function my_plugin_product_tabs_panel_tab() {

	echo '<li class="my_plugin_tab"><a href="#my_plugin_tabs">' . __( 'My Plugin' ) . '</a></li>';

}



add_action( 'woocommerce_product_write_panels', 'my_plugin_product_rates_panel_content' );



/**

 * Adds the tab panel to the Product Data postbox in the product interface

 */

function my_plugin_product_rates_panel_content() {



  $tab_icon = $this->plugin_url() . '/assets/product-data-icon.png';



  if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {

    $style = 'padding:5px 5px 5px 28px;background-image:url(' . $tab_icon . ');background-repeat:no-repeat;background-position:5px 7px;';

    $active_style = '';

  } else {

    $style = 'padding:9px 9px 9px 34px;line-height:16px;border-bottom:1px solid #d5d5d5;text-shadow:0 1px 1px #fff;color:#555555;background-image:url(' . $tab_icon . ');background-repeat:no-repeat;background-position:9px 9px;';

    $active_style = '#woocommerce-product-data ul.product_data_tabs li.my_plugin_tab.active a { border-bottom: 1px solid #F8F8F8; }';

  }

  ?>

  <style type="text/css">

    #woocommerce-product-data ul.product_data_tabs li.my_plugin_tab a { <?php echo $style; ?> }

    <?php echo $active_style; ?>

  </style>



  ...

</pre>
<h2>Conclusion</h2>
<p>Well, that about does it.  As I said in the intro, any more refinements I come up with I'll do my best to update/add here, and if you find anything feel free to mention it in the comments.  Hopefully WooCommerce 2.0 will be released before all too long and this guide will be one for the ages.</p>
<p>The post <a href="http://www.skyverge.com/blog/migrating-your-plugin-woocommerce-2-0/">Guide to Migrating Your Plugin to WooCommerce 2.0</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/migrating-your-plugin-woocommerce-2-0/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>WooCommerce UPS Shipping Now Available</title>
		<link>http://www.skyverge.com/blog/woocommerce-ups-shipping-now-available/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=woocommerce-ups-shipping-now-available</link>
		<comments>http://www.skyverge.com/blog/woocommerce-ups-shipping-now-available/#comments</comments>
		<pubDate>Fri, 11 Jan 2013 18:24:43 +0000</pubDate>
		<dc:creator>Max Rice</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[shipping]]></category>
		<category><![CDATA[ups]]></category>
		<category><![CDATA[woocommerce]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=1068</guid>
		<description><![CDATA[<p>With the official WooCommerce UPS Shipping extension undergoing a rewrite, we&#8217;ve made our WooCommerce UPS Shipping extension available for purchase. This connects your WooCommerce store to UPS and displays real-time shipping rates and estimates. Some key features: Show Negotiated Rates Use simple Table Rates/Pack Tables to define how many products should be in different sizes [...]</p><p>The post <a href="http://www.skyverge.com/blog/woocommerce-ups-shipping-now-available/">WooCommerce UPS Shipping Now Available</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.skyverge.com/shop/wordpress-plugins/woocommerce-ups-shipping/"><img src="https://www.skyverge.com/wp-content/uploads/2013/01/woocommerce-ups-logo.png" alt="woocommerce-ups-logo" width="200" height="200" class="alignright size-full wp-image-1053" /></a></p>
<p>With the official WooCommerce UPS Shipping extension undergoing a <a href="#">rewrite</a>, we&#8217;ve made our WooCommerce UPS Shipping extension available for purchase. This connects your WooCommerce store to UPS and displays real-time shipping rates and estimates. Some key features:</p>
<ul>
<li>Show Negotiated Rates</li>
<li>Use simple Table Rates/Pack Tables to define how many products should be in different sizes boxes.</li>
<li>Include delivery estimates (e.g. Delivers by Wednesday at 10:30 AM) with rates</li>
<li>And much more! See <a href="http://www.skyverge.com/shop/wordpress-plugins/woocommerce-ups-shipping/">full list of features</a></li>
</ul>
<p><a class="zoom" href="https://www.skyverge.com/wp-content/uploads/2013/01/woocommerce-ups-shipping-rates-screenshot.png" rel="description"><img src="https://www.skyverge.com/wp-content/uploads/2013/01/woocommerce-ups-shipping-rates-screenshot-300x163.png" alt="woocommerce-ups-shipping-rates-screenshot" width="300" height="163" class="aligncenter size-medium wp-image-1051" /></a></p>
<p>Visit the <a href="http://www.skyverge.com/shop/wordpress-plugins/woocommerce-ups-shipping/">WooCommerce UPS Shipping</a> product page to learn more and purchase your copy now!</p>
<p>The post <a href="http://www.skyverge.com/blog/woocommerce-ups-shipping-now-available/">WooCommerce UPS Shipping Now Available</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/woocommerce-ups-shipping-now-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tweaking the WooCommerce Order Admin: Searching For Custom Fields</title>
		<link>http://www.skyverge.com/blog/searching-custom-fields-woocommerce-order-admin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=searching-custom-fields-woocommerce-order-admin</link>
		<comments>http://www.skyverge.com/blog/searching-custom-fields-woocommerce-order-admin/#comments</comments>
		<pubDate>Thu, 13 Dec 2012 04:26:33 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[woocommerce]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=962</guid>
		<description><![CDATA[<p>The WooCommerce Order Admin allows you to search for ordres by the following fields: order key billing first name billing last name billing company billing address 1 billing address 2 billing city billing postcode billing country billing state billing email billing phone order items But what if you want to search by another order field? [...]</p><p>The post <a href="http://www.skyverge.com/blog/searching-custom-fields-woocommerce-order-admin/">Tweaking the WooCommerce Order Admin: Searching For Custom Fields</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><a class="zoom" href="/wp-content/uploads/2012/12/woocommerce-order-admin-searching.png"><img src="/wp-content/uploads/2012/12/woocommerce-order-admin-searching-588x156.png" alt="" title="woocommerce-order-admin-searching" width="588" height="156" class="aligncenter size-large wp-image-963" /></a></p>
<p>The WooCommerce Order Admin allows you to search for ordres by the following fields:</p>
<ul>
<li>order key</li>
<li>billing first name</li>
<li>billing last name</li>
<li>billing company</li>
<li>billing address 1</li>
<li>billing address 2</li>
<li>billing city</li>
<li>billing postcode</li>
<li>billing country</li>
<li>billing state</li>
<li>billing email</li>
<li>billing phone</li>
<li>order items</li>
</ul>
<p>But what if you want to search by another order field?  Perhaps the order total?  Well it&#8217;s as easy as adding something like the following to your themes <code>functions.php</code>:</p>
<pre>

add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_order_total' );



function woocommerce_shop_order_search_order_total( $search_fields ) {

  $search_fields[] = '_order_total';

  return $search_fields;

}

</pre>
<p>With that simple snippet active you can now search by order total.  Note that with the numerical fields like total, you&#8217;d need to search with no thousands separator, and a period for the decimal place holder, ie:  1000.50 regardless of how you have configured WooCommerce to display totals on the frontend.  That&#8217;s due to the way the numbers are stored within WooCommerce.  Using this technique you can even search by custom post meta that you may be adding to the order records.</p>
<p>The post <a href="http://www.skyverge.com/blog/searching-custom-fields-woocommerce-order-admin/">Tweaking the WooCommerce Order Admin: Searching For Custom Fields</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/searching-custom-fields-woocommerce-order-admin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Override WooCommerce Widgets</title>
		<link>http://www.skyverge.com/blog/overriddin-woocommerce-widgets/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=overriddin-woocommerce-widgets</link>
		<comments>http://www.skyverge.com/blog/overriddin-woocommerce-widgets/#comments</comments>
		<pubDate>Sun, 02 Dec 2012 03:41:56 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[woocommerce]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=945</guid>
		<description><![CDATA[<p>While it&#8217;s not technically possible to override a WordPress widget (and remember WooCommerce widgets are nothing more than WordPress widgets), WooCommerce is just so extendable and pluggable and flexible, that some widget functionality can be nearly completely overridden just using the standard WooCommerce template files and/or template functions. For the widgets that aren&#8217;t as pluggable, [...]</p><p>The post <a href="http://www.skyverge.com/blog/overriddin-woocommerce-widgets/">How to Override WooCommerce Widgets</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2012/03/woocommerce_logo_leader.png" alt="" title="WooCommerce" width="588" height="130" class="aligncenter size-full wp-image-412" /></p>
<p>While it&#8217;s not technically possible to override a WordPress widget (and remember WooCommerce widgets are nothing more than WordPress widgets), WooCommerce is just so extendable and pluggable and flexible, that some widget functionality can be nearly completely overridden just using the standard WooCommerce <a href="/articles/wordpress/how-to-override-woocommerce-template-files/">template files</a> and/or template functions.  For the widgets that aren&#8217;t as pluggable, or if you need greater control, you have the option to un-register a core WooCommerce widget and subclass it, or even duplicate it and change it wholesale, all without modifying a single core file, thus maintaining a clean upgrade path.</p>
<p>Your widget override options, listed in order of preference, starting with the most preferred, down to the least preferred but most powerful, are as follows:</p>
<ol>
<li>Use the <code>widget_display_callback</code> filter to alter configuration details</li>
<li>Hook into any provided filters/actions</li>
<li>Override a WooCommerce template file</li>
<li>Override a pluggable WooCommerce template function</li>
<li>Subclass, modify and register a widget</li>
<li>Duplicate, modify and register a widget</li>
</ol>
<p>The rest of this article will be devoted to describing, with code examples where applicable, these six options.  Note also that while this is written with WooCommerce in mind, most of the strategies described are completely applicable to any WordPress widgets.</p>
<h2>Option 1 &#8211; Hook into <code>widget_display_callback</code> filter</h2>
<p>You can hook onto the <code>widget_display_callback</code> filter to change the configuration settings of a widget on-the-fly.  Not really sure how useful this is, and I&#8217;m not covering it in great detail as this article is geared towards more substantial behavior overrides.  Still, a quick example of how you might use it, here changing the Cart widget title:</p>
<pre class="brush: php; title: ; notranslate">
add_filter( 'widget_display_callback', 'rename_widget', 10, 3 );

function rename_widget( $settings, $widget, $args ) {

  if ( get_class( $widget ) == 'Custom_WooCommerce_Widget_Cart' ) {
    $settings['title'] = 'My Cart';
  }

  return $settings;
}
</pre>
<h2>Option 2 &#8211; Hook into widget filters/actions</h2>
<p>I didn&#8217;t include this method initially as I don&#8217;t know how many widgets actually provide their own action/filter hooks for modifying functionality, but there&#8217;s certainly no reason that they couldn&#8217;t, and if they should, this would be an ideal way to change the widget behavior.  I won&#8217;t cover the basics of using WordPress actions/filters, for that check out the <a href="http://codex.wordpress.org/Plugin_API">WordPress Plugin API codex page</a>.</p>
<h2>Option 3 &#8211; Override a WooCommerce widget template file</h2>
<p>This is the next most preferred means of changing a WooCommerce widget&#8217;s behavior, but it&#8217;s not always possible.  To determine whether you can use this method, you&#8217;ll have to inspect the widget class in question.  Lets use the WooCommerce Cart widget as an example, which produces a mini cart like the following when active:</p>
<p><img src="/wp-content/uploads/2012/12/wc-mini-cart.png" alt="" title="WC Mini Cart" width="276" height="242" class="aligncenter size-full wp-image-946" /></p>
<p>The code for this widget can be found at <code>woocommerce/widgets/widget-cart.php</code>.  If we take a look at that file, we&#8217;ll find that it doesn&#8217;t contain much beyond the boilerplate widget code, though it does contain the following line:</p>
<pre class="brush: php; title: ; notranslate">
$woocommerce-&gt;mfunc_wrapper( 'woocommerce_mini_cart()', 'woocommerce_mini_cart', array( 'list_class' =&gt; $hide_if_empty ? 'hide_cart_widget_if_empty' : '' ) );
</pre>
<p>Without diving into the specifics of what&#8217;s going on here, suffice it to say that this results in a call to the <code>woocommerce_mini_cart()</code> function, which will do most of the work of creating this widget on the frontend.  When we look at the <code>woocommerce_mini_cart()</code>, found in <code>woocommerce/woocommerce-template.php</code>, we see that it in turn does very little other than loading <code>cart/mini-cart.php</code>:</p>
<pre class="brush: php; title: ; notranslate">woocommerce_get_template( 'cart/mini-cart.php', $args );</pre>
<p>Which you can find at <code>woocommerce/cart/mini-cart.php</code> and actually contains the code that renders that mini cart widget.</p>
<p>Now this may seem like a lot of effort or unnecessary code just to display a mini cart, but what this design provides is quite a lot of flexibility, with multiple avenues for modifying the widget behavior.  Thanks to all that flexibility we can completely change the look and feel of this widget by simply <a href="/articles/wordpress/how-to-override-woocommerce-template-files/">overriding the mini-cart.php template file</a>.  This is something I&#8217;ve covered fully in another article, but the overview is to create a directory named <code>woocommerce</code> within your theme, copy over the template file in question, and modify things to our hearts content.  In this example we&#8217;d copy <code>woocommerce/templates/cart/mini-cart.php</code> to <code><em>yourtheme</em>/woocommerce/cart/mini-cart.php</code> and change whatever we want in that file.  The template file in the theme will be used in place of the core WooCommerce template.</p>
<h2>Option 4 &#8211; Override a plugable widget template function</h2>
<p>This method is quite related to the template file method described in the previous section.  If you&#8217;ve read through and paid attention to Option 3, you&#8217;ll remember the function <code>woocommerce_mini_cart()</code>, found in <code>woocommerce/woocommerce-template.php</code> which loaded the <code>mini-cart.php</code> template file.  This function is known as a pluggable function because it can be replaced with your own custom version.  The full function looks like the following:</p>
<pre class="brush: php; title: ; notranslate">
if ( ! function_exists( 'woocommerce_mini_cart' ) ) {

  function woocommerce_mini_cart( $args = array() ) {

    $defaults = array( 'list_class' =&gt; '' );
    $args = wp_parse_args( $args, $defaults );
    woocommerce_get_template( 'cart/mini-cart.php', $args );

  }

}
</pre>
<p>Thanks to that <code>function_exists()</code> check, we are actually given the opportunity to &#8220;plug-in&#8221; our own function implementation <em>before</em> this one is loaded; hence the term &#8220;pluggable&#8221;.  We can do so by simply copying this function to our theme&#8217;s <code>functions.php</code> and making whatever changes we might want, including loading the same or perhaps an entirely different template file.</p>
<p>Keep in mind that not all WooCommerce widgets are structured to use template functions and files, so you&#8217;ll have to actually look at the code for the widget in question and determine whether this override option is available to you.  If it is, and allows you to do what you need, that&#8217;s great as like the previous options it&#8217;s very easy, safe, and doesn&#8217;t impact WooCommerce upgrades.</p>
<h2>Option 5 &#8211; Subclass, modify and register a widget</h2>
<p>Among the benefits of this option are: the fact that we can do this with any widget regardless of whether it uses a pluggable template function, by subclassing we can inherit some behavior while overriding other, we can change anything about the plugin&#8217;s behavior, and this is quite upgrade-safe.  That is unless your child class depends on a part of the parent widget implementation which happens to change in a subsequent release; something that is possible but probably unlikely, and could be addressed with the final option, described after this one.</p>
<p>The basic recipe for the subclass method is as follows:</p>
<ol>
<li>Subclass the widget in question in a new widget class, changing whatever functionality you desire.</li>
<li>Unregister the widget in question</li>
<li>Register your new widget</li>
<li>Use the new widget!</li>
</ol>
<p>As an example, lets say we want to change the WooCommerce Best Sellers widget, which displays a list of the best selling products on your site.  What we want to change about this widget is immaterial, the basic steps will remain the same.  First we take a look at the widget code, which can be found at <code>woocommerce/widgets/widget-best_seller.php</code> to determine whether we can use one of the more preferred modes of overriding described above.  It&#8217;s pretty obvious that the bulk of code, both for accessing the database, as well as rendering the best sellers list, is contained right within the <code>widget()</code> method, and with no real filter/action hooks, options 1-4 are out.  In addition to the <code>widget()</code> method, there are a number of other methods such as the constructor and widget form display, which perhaps we don&#8217;t care about changing, hence making a subclass the ideal solution as we can rely on the parent for the implementation of those methods, and focus on just changing the main <code>widget()</code> method to do whatever it is we need.</p>
<p>So we&#8217;ll start by creating a new file in our theme named:  <code><em>my-theme</em>/widgets/widget-best_sellers.php</code>, and containing a new class class that extends <code>WooCommerce_Widget_Best_Sellers</code> and copying in the entire <code>widget()</code> method from <code>woocommerce/widgets/widget-best_seller.php</code>:</p>
<pre class="brush: php; title: ; notranslate">
class Custom_WooCommerce_Widget_Best_Sellers extends WooCommerce_Widget_Best_Sellers {

  function widget( $args, $instance ) {
    // copy the widget function from woocommerce/widgets/widget-best_seller.php
  }

}
</pre>
<p id="subclass-example-code">Then add the following code to your theme&#8217;s <code>functions.php</code> to unregister the WooCommerce Best Sellers widget and register our custom one in its place:</p>
<pre class="brush: php; title: ; notranslate">
add_action( 'widgets_init', 'override_woocommerce_widgets', 15 );

function override_woocommerce_widgets() {
  // Ensure our parent class exists to avoid fatal error (thanks Wilgert!)

  if ( class_exists( 'WooCommerce_Widget_Best_Sellers' ) ) {
    unregister_widget( 'WooCommerce_Widget_Best_Sellers' );

    include_once( 'widgets/widget-best_sellers.php' );

    register_widget( 'Custom_WooCommerce_Widget_Best_Sellers' );
  }

}
</pre>
<p>Now you&#8217;ll be able to use this new widget in exactly the same manner as the old one, and change any of the functionality you need in the <code>widget()</code> method.  There will be no confusion in the admin UI as there will only be one version of the Best Sellers widget shown; your custom version.  Future updates of WooCommerce should be relatively painless as you haven&#8217;t actually modified any core files.</p>
<h2>Option 6 &#8211; Duplicate, modify and register a widget</h2>
<p>This approach is exactly the same as option 5, except you&#8217;ll need to copy the entire parent widget file over, and you won&#8217;t be extending from it as we did in the previous option.  Here we&#8217;re literally creating an entirely new widget and swapping it in place of the old, so it&#8217;s fairly brute force, but on the other hand does not rely on any implementation details of the original widget.  The same basic code is used to unregister and register the widgets.</p>
<h2>Conclusion</h2>
<p>And so there you have it, 6 different ways of seamlessly and safely modifying widget behavior.  I&#8217;d be curious to hear if you end up overriding any widgets, WooCommerce or otherwise, which widgets you change and what for; let me know in the comments section below!</p>
<p>The post <a href="http://www.skyverge.com/blog/overriddin-woocommerce-widgets/">How to Override WooCommerce Widgets</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/overriddin-woocommerce-widgets/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Don&#039;t Share Terms Between WordPress Taxonomies</title>
		<link>http://www.skyverge.com/blog/dont-share-terms-between-wordpress-taxonomies/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dont-share-terms-between-wordpress-taxonomies</link>
		<comments>http://www.skyverge.com/blog/dont-share-terms-between-wordpress-taxonomies/#comments</comments>
		<pubDate>Tue, 20 Nov 2012 22:18:25 +0000</pubDate>
		<dc:creator>Justin Stern</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[woocommerce]]></category>

		<guid isPermaLink="false">http://www.skyverge.com/?p=934</guid>
		<description><![CDATA[<p>By default WordPress will reuse terms with the same name and slug between different taxonomies. For instance, if you add the term &#8216;red&#8217; as a tag, and then add the category &#8216;red&#8217;, the same wp_terms record will be shared between them. This is also true for any custom taxonomies you define (remember that despite their [...]</p><p>The post <a href="http://www.skyverge.com/blog/dont-share-terms-between-wordpress-taxonomies/">Don&#039;t Share Terms Between WordPress Taxonomies</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2012/04/wordpress.png" alt="" title="WordPress" width="200" height="200" class="alignleft size-full wp-image-440" />By default WordPress will reuse terms with the same name and slug between different taxonomies.  For instance, if you add the term &#8216;red&#8217; as a tag, and then add the category &#8216;red&#8217;, the same <code>wp_terms</code> record will be shared between them.  This is also true for any custom taxonomies you define (remember that despite their seeming differences, WordPress tags and categories are both implemented as taxonomies).  Now, in general this is fine; if the name and slug are the same, then just given the fact that all term records are stored in a single table forces them to be shared across different taxonomies.</p>
<p>However, what if you don&#8217;t care so much about the slug, and want to be able to use the same term name within multiple taxonomies, but don&#8217;t want the <code>wp_terms</code> record shared?  I&#8217;ll admit this might not be a typical case, but it came up for me recently when doing some WooCommerce work, specifically because I wanted to be able to attach different term meta to each of the terms with the same name, so they couldn&#8217;t be shared between taxonomies.  (Side note:  WooCommerce allows you to attach meta information to term records, a really cool extension to WordPress with lots of uses, and I plan to cover that implementation in a future article.)  One simple way to stop the records from being shared is to make the admin user define a unique slug for each term that shares a common name with another taxonomical term, ie: &#8216;Red&#8217;, &#8216;red&#8217; in taxonomy &#8216;A&#8217; and &#8216;Red&#8217;, &#8216;red-2&#8242; in taxonomy &#8216;B&#8217;, etc.  Obviously the drawback is that you have to remember to do this, have to remember how many different &#8216;red&#8217; terms there are, all easy stuff to forget until it&#8217;s too late.  So, as usual I&#8217;ve put together a little modification that you can add to your theme&#8217;s functions.php, or to your very own <a href="/articles/wordpress/creating-custom-plugin-for-your-woocommerce-shop/">custom site plugin</a> and explained below.</p>
<h2>The Code</h2>
<p>The implementation is actually fairly simple:  we hook a filter to &#8216;pre_insert_term&#8217; and temporarily rename the term as needed to generate a unique slug and thus a separate term record, then after the term is created we fix the name back to what the user originally specified.  This is done only if a term slug is <em>not</em> given; we assume the user had something special in mind if they went through the trouble of providing a slug.  And with that, here&#8217;s the code:</p>
<pre>

add_filter( 'pre_insert_term', 'foxrunsoftware_pre_insert_term', 10, 2 );



/**

 * This filter temporarily renames any terms to force a unique slug when they

 * would otherwise not be unique.  This is to overcome a "feature" with

 * WordPress, whereby terms are recycled among different taxonomies rather than

 * being created new with a unique slug.  As an example, if the term 'red'

 * exists in a taxonomy and 'red' is added to another taxonomy, it will be

 * temporarily named as 'red 2', which forces a unique slug to be created, then

 * we remove the name counter suffix after the term is created.

 *

 * @param string $term the term name

 * @param string $taxonomy the taxonomy name

 *

 * @return string the term name

 */

function foxrunsoftware_pre_insert_term( $term, $taxonomy ) {



  // if no slug was specified

  if ( empty( $_REQUEST['slug'] ) ) {

    $slug = sanitize_title( $term );



    // check whether a unique slug needs to be generated

    $new_slug = wp_unique_term_slug( $slug, (object) array( 'parent' => 0, 'taxonomy' => $taxonomy ) );



    if ( $new_slug != $slug ) {

      // append the unique slug counter to the end of the term name, to force uniqueness

      $term .= ' ' . substr( $new_slug, strrpos( $new_slug, '-' ) + 1 );



      // hook so we can fix the term name back to what it should be

      add_action( 'created_term', 'foxrunsoftware_created_term', 10, 3 );

    }

  }



  return $term;

}

</pre>
<p>As you can see, after changing the term name if needed, a second action is added to fix the modified term name.  The implementation of that function is as follows:</p>
<pre>

/**

 * This action removes the temporary counter which is added to terms to force

 * uniqueness.

 *

 * See the commends for the foxrunsoftware_pre_insert_term() function

 * for the full details.

 *

 * @see foxrunsoftware_pre_insert_term()

 *

 * @param int $term_id term identifier

 * @param int $tt_id term taxonomy identifier

 * @param string $taxonomy taxonomy name

 */

function foxrunsoftware_created_term( $term_id, $tt_id, $taxonomy ) {



  $term = get_term( $term_id, $taxonomy );



  // get rid of the temporary counter we added to the name

  $name = substr( $term->name, 0, strrpos( $term->name, ' ' ) );



  // update and we're done!

  wp_update_term( $term_id, $taxonomy, array( 'name' => $name ) );

}

</pre>
<p>And that&#8217;s the whole of it.  If there&#8217;s anyone else out there who did not want their terms shared between taxonomies, let me know in the comments below, I&#8217;d be curious to hear what you&#8217;re doing!</p>
<p>The post <a href="http://www.skyverge.com/blog/dont-share-terms-between-wordpress-taxonomies/">Don&#039;t Share Terms Between WordPress Taxonomies</a> appeared first on <a href="http://www.skyverge.com">SkyVerge</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.skyverge.com/blog/dont-share-terms-between-wordpress-taxonomies/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
