4elements, Amsterdam, Holland

  1. Configuring Product Settings in WooCommerce

    In the first two parts of this series, you learned how to install WooCommerce and configure its settings. Now it's time to add some products to your store!

    But before you can add any products, you need to configure your product settings, which is what this tutorial will work . Let's take a look at the options in the WooCommerce Products menu:

    What You'll Need

    To complete this tutorial you'll need:

    • An installation of WordPress, with Administrator access
    • The WooCommerce plugin installed and activated
    • WooCommerce settings configured.

    Configuring Product Settings

    Let's take a look at the options in the WooCommerce Products menu:

    The screens available to you in the Products section of the WooCommerce admin are:

    • Products are where your products are listed
    • Add Product is where you add new products
    • Categories are where you add and configure product categories (which are distinct from the categories elsewhere in your site)
    • Tags are where you add and configure product tags (again these are distinct from the tags in the rest of your site)
    • Shipping Classes are where you add shipping classes which you can then apply to products
    • Attributes are where we add attributes and give each of them a set of terms. These work in a similar way to taxonomies.

    I'll start by working through the last four of these and demonstrating what you need to add.

    Adding Product Categories

    Product categories work in a similar way to categories in your main WordPress site, but they are not the same thing - when a visitor looks at your product category pages in your store, they won't see blog posts, and when they look at your category archives in your blog, they won't see products. Product categories have one feature which normal categories don't: You can give them a featured image.

    The Product Categories screen lets you add new categories, define a slug and description for each, and identify a parent category if you are using hierarchical product categories:

    As you can see above, you can also add a thumbnail to each category, which will be used in the main shop page.

    My store will be selling the books that I've written, so I'm adding Books as my product category. I add a category, click on Add New Product Category and then it's displayed on the right hand side:

    Note that as with normal categories, you can also add new product categories when you're adding products, from the product editing screen.

    Adding Product Tags

    Product tags work in a similar way to tags in the rest of your site, but again they are separate. You can add as many tags as you want, either in the Product Tags screen or when adding your products:

    Add the information for your tag, click on Add New Product Tag and it will appear in the list.

    Adding Shipping Classes

    You may remember I touched on shipping classes in the previous tutorial but explained that you would need to add them when configuring product settings. In the Shipping Classes screen you add classes which you then assign to individual products. I'm going to add two classes: standard and heavy. If a book is particularly heavy, I can give it the heavy class and then buyers will be charged extra postage.

    Start by adding your classes in the Shipping Classes screen:

    Having done that, you need to return to the shipping settings to define costs for each class. Go to WooCommerce > Settings > Shipping > Flat Rate:

    As you can see I've added an extra £2.00 to the Heavy Items class. I've also selected Per Item from the drop down menu, meaning that the extra £2.00 will be added for each heavy item purchased and not for the order as a whole. If you want to just apply the extra charge once, select Per Order instead.

    Save your changes by clicking Save Changes and the rate for that class will be saved and automatically added to any orders containing items which you assign the class to.

    Adding Attributes

    Attributes work like taxonomies and not categories: each attribute you add to WooCommerce is a taxonomy which you then add terms to.

    In my site, I'm going to add two attributes: publisher and level. This means that each term in 'Publisher', for example, is equivalent to a category.

    First, add the attributes in the Attributes screen:

    The Type field is important and gives you two options:

    • Text allows administrators and other users who are able to add products to your store to type in the text for the attribute's term when adding a product. This gives more flexibility but runs the risk of having lots of similar terms created.
    • Select is for when users will only be able to select terms for an attribute from a predefined list in a drop down box. You need to predefine the terms first. This is less flexible but allows for greater control and accuracy and is what I've done here. 

    To define the terms for each of my attributes, I click the symbol to the right of the attribute's name in the list on the right: if you hover over the symbol, you'll see a link saying Configure terms.

    This takes me to the terms screen for my attribute:

    Simply add your terms in the same way as you would add categories: note that like categories, these are hierarchical.

    Summary

    So that's all of the product settings configured. You have attributes, categories and tags ready to assign to your products, as well as shipping classes. The next step is to add the first product. 

    In the next two tutorials I'll work through the process of adding physical products to your store and adding virtual or downloadable products to your store.

     

    0 Comments

    Leave a comment › Posted in: Daily

    1. The Beginner’s Guide to WordPress Taxonomies: Themes or Plugins?

      In this series, we're taking a look at what WordPress taxonomies are, their definition, when to use them, and how to incorporate them into our themes. To make sure we're covering this in as much detail as possible, we're approaching this from the perspective of a beginner.

      As mentioned in the first post in the series, this series isn't aimed only at beginners. Perhaps you're an intermediate WordPress developer who is looking to begin branching out into new APIs and implementing new features into your work and taxonomies fit the bill for exactly that.

      Whatever the case, we're doing what we can to make sure that you're armed with as much information as possible when it comes to incorporating custom taxonomies into your WordPress projects.

      Why vs. When

      Before we look at an actual implementation of how to incorporate taxonomies, we need to talk about some of the challenges that come with incorporating taxonomies into our work.

      Specifically, should taxonomies be included as part of a theme or in a plugin? This question is really more of a question of "why should we include taxonomies this way?" and "when should we include taxonomies this way?"

      And to answer that, it's important to distinguish between the two options that we have and how data is stored.

      How The Data Is Stored

      First, let's discuss how taxonomies are stored internally within WordPress. Taxonomies consist of two components: A taxonomy and a term.

      1. A taxonomy represents how information is grouped together.
      2. A term represents the type of data that belongs to that taxonomy.

      For example, when thinking of Post Formats, the taxonomy is Post Format and the terms are Standard, Video, Image, Link, and so on. Similarly, another taxonomy may be Photography and the terms may be Film and Digital.

      In the most basic case, the default WordPress taxonomy and term pairing is Category and Uncategorized that's provided with every installation.

      Now, from here, it's important to understand how this data is managed in the WordPress database. There are three database tables each of which play a role in the relationship between taxonomies and their associated terms.

      Assuming that you're working with the default installation (that is, the table prefix is wp_), then you'll have the following tables each with the corresponding responsibilities:

      1. wp_terms represents the terms that belong to various taxonomies. This means that if you have a Photography taxonomy with two terms being Film and Digital and you have a taxonomy called Type with Color and Black and White being terms, then Film, Digital, and Color will all reside within the wp_terms table.
      2. wp_term_taxonomy is a database table that's responsible for storing the description of the terms stored in the wp_terms table. Say, for example, you have a Color term and the term is described as "Photographs that are developed in vibrant colors." Then this description would reside in the wp_term_taxonomy table.
      3. The wp_term_relationships is arguably the one that has the largest learning curve for new developers. This table maintains the connection between what taxonomies are related to which post types. For example, given a default installation, this table will store the relationship between the category term and each post to which it is associated.

      Now that we have an understanding as to how data is stored, we can discuss when taxonomies make sense within the context of themes and within the context of plugins.

      Themes or Plugins?

      Generally speaking, a good rule of thumb is to note that WordPress themes should be for presentation of data and plugins should be for functionality. That is, themes provide the format for how the data looks, and plugins extend core functionality of WordPress.

      There is also the notion of extensions which are like theme-specific plugins and plugin-specific plugins, but that's beyond the scope of this article. For now, let's keep the discussion at the level of themes and plugins.

      Let's say that you are working on a theme and you want to introduce a custom taxonomy into the theme. In keeping consistent with our examples used throughout the series, let's say that you want to create a portfolio theme and you want to introduce Photography taxonomy. After all, the theme is going to allow users to showcase their work.

      Then, let's say that you want to work on the same theme in a year or so but you want to perform a major upgrade. Perhaps you want to generalize the taxonomies so that people don't have to use it just for photography. Instead, they can use it for short poems or writings, drawings, and so on. 

      The problem is that you now have the Photography taxonomy hardcoded into the theme such that everyone who uses it and installs it gets that particular taxonomy regardless of if they want to showcase photography or not.

      Sure, it's completely possible to rebuild the theme from the ground up and abstract the taxonomy function into something more general, but what happens for the users who want to upgrade? Do they lose the data that they've spent months or years working with? How is their data going to be organized? Are they stuck with the current version of the theme with which they're working?

      Obviously, there's a lot to consider whenever you're working on a theme like this. But that's where the importance of segmenting presentation and functionality comes into play.

      It's completely possible to build a theme designed to showcase work in a portfolio style without actually having to hardcode any type of taxonomy into the theme. Instead, build the functionality into a plugin and then install the plugin alongside the theme with which you're building. You then get the advantages of the portfolio presentation without having users locked into using your theme for however long and potentially losing their data when upgrading to a new theme.

      A Word About Compatibility

      For many of the reasons listed above, it's easy to see why implementing custom taxonomies within the context of plugins makes sense.

      This is not to say that it should never be done in themes. After all, there are niche themes that target a very specific audience and that seek to provide an all-in-one solution for their customers. That's fine, but if you're looking to introduce this type of functionality with the widest possible appeal, then building the functionality into a plugin makes a lot of sense.

      Not only do you get the benefit of giving users the ability to port their data from theme to theme without losing the categorization of their data, but you also give them the benefit of being able to maintain independence between the presentation of their data and the storage of their data.

      And if you're a theme developer, you can still work to create themes that are designed specifically around the plugin. Perhaps you'd want to offer a theme for photographers, one for writers, and one for artists. With this strategy, you're able to still aim to capture a certain type of the market all the while making your plugin compatible with the variations of your work freeing you up to work on different themes and giving your customers the ability to move between themes all while still using your products.

      Up Next

      Since we've reviewed how WordPress manages taxonomies within the database, and we've looked at some reasons as to why themes and plugins should work in conjunction with one another to offer specific features, we're going to be looking at how we can create our own plugin that implements custom taxonomy functionality that we've been using as example data throughout this series.

      In the meantime, feel free to leave any comments, questions, or general feedback in the comment field below.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. New Course: Better Web Apps With AngularUI

      AngularJS is a unique and amazing front-end web framework, and AngularUI is a suite of tools made possible by Angular's extensibility. In Better Web Apps With AngularUI, Tuts+ instructor Andrew Burgess will take you through each of the utilities AngularUI provides. You’ll see what they can do, how to use them, and how AngularUI can bring a whole new set of features to your Angular applications.

      You can take our new course straight away with a completely free 14 day trial of a Tuts+ subscription. Start your free 14 day trial today, to access this course and hundreds of others.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Generate Notifications From Your Web App With the Pushover API

      Final product image
      What You'll Be Creating

      Pushover is one of my favorite services over the past few years; it makes it easy and inexpensive for developers to send push notifications to iOS and Android devices without having to develop their own application. 

      It also recently added desktop browser notifications as well. The service is largely free for low level usage and the apps only require a $4.99 fee after a five-day free trial; there is no monthly fee. Working with its API is straightforward and there are libraries available for a handful of different languages.

      While a number of front-end app developers integrate with Pushover, e.g. IT, I find it most useful as a developer for receiving notifications related to my own applications and web servers. For example, I've integrated Pushover into my Simple Monitoring application to alert me to website failures as well as sending twice daily heartbeat notifications when nothing is wrong. If MySQL fails or my DNS goes down, I'll receive a speedy alert to my iPhone. 

      Similarly, I integrated Pushover into SimplifyEmail to send notifications when emails with specific keywords arrive such as "urgent" or from specific senders such as "Tom McFarlin" (Envato's Code editor).

      Here's what Pushover alerts look like on your phone:

      Sample heartbeat and failure alerts from Simple Monitor using Pushover

      Pushover offers a variety of sounds to customize notifications and it also supports user-configurable quiet hours, so you don't have to be woken up in the middle of the night unless you want to be:

      Configure Quiet Hours within Pushover

      Just remember, real SysAdmins don't sleep!

      Getting Started With Pushover

      To get started with Pushover, visit the website and sign up:

      Sign Up for Pushover

      Then, install either mobile application or the desktop browser notification support. Each offers five days of free usage before you'll be required to purchase each for $4.99. For the iOS and Android apps, you can just download them from the app stores.

      Install Pushover for iOS

      When you install the mobile app, it will ask you to log in and specify a device name of your choosing, e.g. iPhone.

      Setting up the desktop browser-based notifications is a bit different. Visit the Pushover for Desktop page and choose a simple name for your Pushover browser notifications:

      Choose Your Desktop Notification Device Name

      Instruct your browser to allow notifications:

      Then, you'll see the Pushover desktop in-browser app:

      The Pushover Browser-based App

      Ultimately, desktop notifications from Pushover will look like this:

      Example of a Pushover Web Notification

      Once you have installed Pushover on your device and web browsers, you can begin sending test notifications from the Pushover website:

      Send

      But the fun is just beginning—let's get started using the Pushover API.

      Developing With the Pushover API

      Pushover requires that you register each application. Just visit your apps page:

      The Pushover Apps Page

       And register a new application:

      Create a New Pushover Application

      You'll be given an API token to use to send notifications from your application:

      An API Token for Pushover Apps

      The Pushover home page offers some simple examples of sending notifications with curl:

      curl_setopt_array($ch = curl_init(), array(
        CURLOPT_URL => "https://api.pushover.net/1/messages.json",
        CURLOPT_POSTFIELDS => array(
          "token" => "your-api-token",
          "user" => "your-user-id",
          "message" => "hello world",
        ),
        CURLOPT_SAFE_UPLOAD => true,
      ));
      curl_exec($ch);
      curl_close($ch);

      But, for Simple Monitor and Simplify Email, I use Chris Schalenborgh's PHP Pushover library. For example, in SimpleMonitor, I use a background CronController that runs all of the tests the end user configures through the web user interface: 

      class CronController extends Controller
      {
        
        public function actionIndex()
          {
            $result = Content::model()->testAll();
      		$this->render('index',array(
      			'result'=>$result,
      		));
      	}
      

      Here's an example of Simple Monitor's list of my checks which trigger different Pushover notification sounds:

      Using Pushover Sounds with Simple Monitor

      My TestAll method, called by cron, processes each of the user-configured tests. If there is a failure, it notifies each registered device. If there is no failure, it determines whether it's time to resend a heartbeat notification, letting me know the monitor is still up and running:

      public function testAll() {
            $str = '';
              $errors = false;	  
        	  // monitor all content items
            $checks = Content::model()->findAll();
            foreach ($checks as $item) {
              // perform the test
              $str.='<p>Checking '.$item['name'].'...';
              $result = Content::model()->test($item['id']);
              // if there is an error send notification to the device
              if (!$result->status) {
                if ($item['type']==self::TYPE_CHANGES)
                  $temp_result_string = 'Page Changed';
                else
                  $temp_result_string = 'Failed';
                $str.=$temp_result_string.'<br />'; 
                $str.='Please check <a href="'.$item['url'].'">'.$item['url'].'</a><br />';
                 if ($item['device_id']==0) {
                   //  send to all devices
                   $devices = Device::model()->findAll();
                   foreach ($devices as $device) {
                     Content::model()->notify($device,$item['name'].' '.$temp_result_string,'Please check into...',$item['url'],'this page',1,$item['sound']);                            
                     $str.='Notifying '.$device['name'].'<br />';
                   }
                 } else {
                   $device = Device::model()->findByPk($item['device_id']);
                   Content::model()->notify($device,$item['name'].' '.$temp_result_string,'Please check into...',$item['url'],'this page',1,$item['sound']) ;               
                   $str.='Notifying '.$device['name'].'<br />';
                 }
                 $str.='</p>';
                $errors = true;
              } else {
                $str.='success</p>';
              }      
            } 
            // check for sending heartbeart
            if (!$errors) {
              // only notify me with heartbeat every heartbeat_interval hours
              // note: cron must run every ten minutes or change 10 below to fit your interval
              // the point of date('i')<10 is to send heartbeat only in first part of any hour
              $setting = Setting::model()->getSettings();
              if ((date('G')% $setting['pushover_heartbeat_interval']) == 0 and date('i')<10) {
                $this->sendHeartbeat();
                $str.='<p>Heartbeat sent.</p>';
              } else {
                $str.='<p>Skipped heartbeat for now.</p>';        
              }
        	  }
        	  return $str;    
          }

      My Notify method is what actually calls the Pushover PHP library to send the notifications. This is what you might use in your own application:

        // send notification to admin mobile device via pushover
        public function notify($device,$title='',$message='',$url='',$urlTitle='',$priority=1,$sound='gamelan',$debug=false) {
          if ($device['send_email']<>Device::SEND_EMAIL) {
            // load pushover key from Settings
            $setting = Setting::model()->getSettings();
            $po = new Pushover();
            $po->setToken($setting['pushover_app_api_token']);
            $po->setUser($device['pushover_user_key']);
            $po->setDevice($device['pushover_device']);
            $po->setSound($sound);
            $po->setTitle($title);
            $po->setMessage($message);
            if ($url<>'') {
              $po->setUrl($url);      
            }
            if ($urlTitle<>'') {
              $po->setUrlTitle($urlTitle);
            }
            $po->setPriority($priority);
            $po->setTimestamp(time());
            $po->setDebug(true);
            $go = $po->send();
            if ($debug) {
              echo '<pre>';
              print_r($go);
              echo '</pre>';      
            }      
          }

      As a developer, I've found Pushover to be tremendously useful for delivering notifications in the absence of a dedicated mobile application. To me, Pushover's mobile app is like a SysAdmin dashboard that I didn't have to build. But it's also great for sending notifications for important emails or other server events. It's also fun to prank your friends if you can get hold of their user tokens and device names; but I would never do that.

      Conclusion

      I hope you enjoy using Pushover as much as I have. If you'd like to explore alternative services to Pushover, check out Boxcar and Panacea. I'd love to hear your thoughts. 

      Please post any comments, corrections, or additional ideas below. You can browse my other Tuts+ tutorials on my author page or follow me on Twitter @reifman.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Magento SEO: Optimizing Pages and Avoiding Duplicate Content Penalties

      In this second part of this series, we’ll explore ways to optimize our category and product pages for best search results. We'll also review some advanced techniques on how to avoid duplicate content penalties from search engines.

      So, without further ado let’s start, as we have a lot to cover here.

      Optimizing Category and Product Pages

      Category and product pages are the soul of any eCommerce website; therefore, it is important to include an effective SEO strategy for these pages so that we can rank well in search results. We’ll discuss best practices for optimizing these two types of pages separately.

      To demonstrate the best practices used for optimizing category pages, I've shown the top search results in Google for the keyword “Patio Furniture” in the following screenshot: 

      Patio Furniture search results in Google

      There are many similarities in these search results. First, they all use the keyword in the title and description. Secondly, they all use the brand name in their page title. Next, they use words like "buy", "shop" and "purchase" in page titles and/or in their meta descriptions. This shows that these pages represent shopping websites. Finally, they all show some positive points in the description, to attract the user. We’ll try to accommodate all these points in our category pages.

      First of all, to append the brand name at the end of each page title, instead of doing this manually for all product and category pages, we can make one change from the admin panel, and it’ll automatically append the brand name at the end of each title.

      To do this, go to System > Configuration > Design > HTML Head, and in the Title Suffix field, enter the brand name after a dash () or pipe sign (|), for instance “– Brand Name”.

      Adding title suffix in Magento HMTL Head

      Optimizing Category Pages

      Now, to edit the page title and meta description for each category, go to Catalog > Manage Categories, open up the desired category, and enter the text in the General Information tab.

      Adding page title and meta description

      Please note that changing the page title doesn't change the category name. These two are separate entities. For the page title, the recommended length is between 50 and 70 characters, including the appended brand name. 

      For a meta description, the recommended length is up to 160 characters. It is imperative to note that if we don’t enter a meta description for category pages, it will use the store's default meta description. In that case, search engines can issue duplicate content penalties assuming that we have same description text entered on two different pages. It is therefore almost mandatory to enter a unique meta description for each category page.

      Optimizing Product Pages

      Coming to page optimization techniques for product pages, let’s first look at some good search results of product pages for the search term “canon rebel t3i”:

      Search results for the term canon rebel t3i

      As you can see, many of the rules defined for category pages are also applicable here. For instance, the intended length of the page title and meta description are the same. They should also contain keywords in the title and meta description, and the brand name should be appended after the page title.

      To edit the page title and meta description text for product pages, go to Catalog > Manage Products, click on the required product name, and enter the text in the Meta Information tab.

      Enter page title and meta description for product pages

      To reiterate, changing a page title won’t affect a product's name, as they are two separate fields. Another important thing to note here is that unlike with category pages, if we don’t specify a meta description for product pages, it will not fall back on the store's default meta description. 

      Instead it will use the first 180 to 200 words of the product description text as the meta description, which is a workable solution. It is still recommended that you write separate text for meta description field, as the first 200 characters of a product description text are not always appealing enough to create user intent, which results in product purchase.

      Optimizing Product and Category URLs

      Finally, the URL is one more thing we should cover regarding category and product page optimization. Generally Magento does an excellent job of creating SEO-friendly and human-readable URLs. Some steps mentioned in the previous tutorial in this series further refined it by eliminating the redundant “index” and category names from product URLs; therefore, up to this point, we’ll have nice URLs in place. 

      However, if you think that your URL keys for some individual product pages or category pages are becoming too lengthy, or contain redundant words like "and", "or", etc, then you can also modify these URL keys by going to Catalog > Manage Products and clicking on the General Information tab for products, or Catalog > Manage Categories and clicking on the General Information tab for categories.

      Changing URL text

      Avoiding Duplicate Content Penalties

      Some of the scariest words in search engine optimization for any eCommerce platform are "duplicate content penalty". Due to the inherent structure of eCommerce websites, there will be a number of circumstances where search engine crawlers assume that you have duplicate content on your pages in your Magento store. 

      Some of these issues will be effectively tackled by the steps advised in the previous part of this series. Yet, there are still more steps you can follow to effectively mitigate the threat of duplicate content penalties.

      Editing the Header Template

      It is important to briefly mention the function of canonical links. Sometimes due to sorting, layered navigation or other factors, different URLs actually point to the same page in a website. 

      Some examples of such URLs are:

      http://www.example.com/products?category=dresses&color=green
      http://www.example.com/products?sortby=total_reviews|des

      http://example.com/dresses/cocktail.html
      http://example.com/dresses/cocktail.html?gclid=ABCD

      To avoid duplicate content penalties, we can add canonical links in the head tag of the page, which look like this:

      <link rel="canonical" href="page.html"/>

      That tells search engines that the preferred location of this URL is http://example.com/dresses/cocktail.html instead of http://example.com/dresses/cocktail.html?gclid=ABCD.

      I have described the steps to enable canonical tags in Magento in a previous article in this series, and in most cases that step alone will take care of many duplicate content problems. 

      But sometimes our duplicate pages may still be cached by search engines, especially if the website has been live prior to turning on the canonical elements. To deal with this situation, we’ll manually add some lines of code into our template head.phtml file, to ensure these canonical tags are called each time a product or category page is opened.

      Open your Magento directory and navigate to app/design/frontend/[theme name]/default/template/page/html/head.phtml. If there is no head.phtml file there, copy it from the location app/design/frontend/base/default/template/page/html/head.phtml and paste it there.

      In this head.phtml file, place the following code, where other <link> tags are mentioned:

      <?php if(Mage::registry(‘product’)): ?>
      <link rel=”canonical” href=”<?php echo Mage::registry(‘product’)->getProductUrl(); ?>” />
      <?php elseif(Mage::registry(‘current_category’)): ?>
      <link rel=”canonical” href=”<?php echo Mage::registry(‘current_category’)->getUrl(); ?>” />
      <?php endif; ?>

      This code will manually add canonical tags on each product and category page. Another great step recommended in this article is to add this code at the end of the head.phtml file:

      <?php
      $actionName = $this->getAction()->getFullActionName();
      if ($actionName == 'catalog_category_view') // Category Page
      {
          $category = Mage::registry('current_category');
          $prodCol = $category->getProductCollection()->addAttributeToFilter('status', 1)->addAttributeToFilter('visibility', array('in' => array(Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG, Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)));
          $tool = $this->getLayout()->createBlock('page/html_pager')->setLimit($this->getLayout()->createBlock('catalog/product_list_toolbar')->getLimit())->setCollection($prodCol);
          $linkPrev = false;
          $linkNext = false;
          if ($tool->getCollection()->getSelectCountSql()) {
              if ($tool->getLastPageNum() > 1) {
                  if (!$tool->isFirstPage()) {
                      $linkPrev = true;
                      if ($tool->getCurrentPage() == 2) {
                          $url = explode('?', $tool->getPreviousPageUrl());
                          $prevUrl = @$url[0];
                      }
                      else {
                          $prevUrl = $tool->getPreviousPageUrl();
                      }
                  }
                  if (!$tool->isLastPage()) {
                      $linkNext = true;
                      $nextUrl = $tool->getNextPageUrl();
                  }
              }
          }
          if ($linkPrev) echo '<link rel="prev" href="' . $prevUrl . '" />';
          if ($linkNext) echo '<link rel="next" href="' . $nextUrl . '" />';
      }
       ?>

      This will implement rel=prev and rel=next for Magento’s pagination, to communicate to the search engine crawlers that the pages being displayed should be interpreted as paginated product listings, and not as duplicate content. The above code will add links like below, when it is on page 3 of the product listing results:

      <link rel="prev" href="http://www.mystore.com/categoryname/subcategory.html?p=2"  />
      <link rel="prev" href="http://www.mystore.com/categoryname/subcategory.html?p=4"  />

      Duplicate Content on Translated Pages

      Magento is superb at providing multi-language support to its users. We have all the autonomy within Magento to set up different languages for our stores. While we’ll dig deep into the SEO considerations for setting up a multi-language store later, it's important to mention a few tips on how to avoid duplicate content penalties for websites using multiple languages. To mitigate this threat we should use the rel="alternate" hreflang="x" tag.

      The best place to put this tag is into the head of the page. As it would be difficult to manually put this into each page’s head tag, the way around it is to use the Miscellaneous Scripts field at System > Configuration > Design > HTML Head > Miscellaneous Scripts

      Example code for this field could be:

      <link rel="alternate" href="http://example.com/en"  hreflang="x-default" />
      <link rel="alternate" href="http://example.com/de"  hreflang="de" />
      <link rel="alternate" href="http://example.com/fr"  hreflang="fr" />
      Miscellaneous Scripts field in Magento

      With all this done, we've made our Magento store quite SEO-friendly, and we have made every possible effort to avoid duplicate content penalties. 

      In the next article of this series, we’ll discuss how to speed up our Magento store to reduce page load time, and also how to enable different schemas into our Magento store to give a professional look to our search engine results.

       

      0 Comments

      Leave a comment › Posted in: Daily

  • Page 3 of 40 pages  < 1 2 3 4 5 >  Last ›
  • Browse the Blog

    Syndicate

    governing-bruise