4elements, Amsterdam, Holland

  1. Website Launch Announcement

    DesignScan, Get insight in your website launches their site www.designscan.me

    After 3 years of development, in spare time, DesignScan is excited to announce the launch of their new service and website. The website goes live today, on Monday, June 2, 2014, and is located at: www.designscan.me

    It is time to retake control of your own website. At the newly launched DesignScan.me, instead of endlessly browsing or talking with web design agencies, owners get insight in their own website (Design age, flaws, Usability and others). DesignScan.me features cutting-edge, in-house developed, software that analyses your website design and reports back to the owner in human understandable language.

    DesignScan.me is on a mission to deliver perfect, readable, insights for website owners and to bring the two worlds together, website owners and web- designers, developers. By doing so we pave the way where we provide website owners with the tools and knowhow, and provide the designers and developers with potential new business, clients.

    ###

    Our website is divided into three main sections: MADE SCANS, DASHBOARD (after login) and SUPPORT. By moving to a more client-centric layout, we allow visitors to access information based on their own choice rather than sift through everything to decide what is of interest to them.

    In de MADE SCANS section our current and new members will find detailed information about the companies we made designscans for, this is also the place where you can start earning credits by participating in our “Vote & Earn” program. The DASHBOARD area is specially designed for our registered members. A place where your designscan results are shown and explained, in a human understandable language.

    The website will feature new types of rich content, inspired by our experience, gathered materials and a great team of people working for DesignScan.me. You will find this content in the SUPPORT section in the form of articles, case studies, videos, presentations, interactive forum and live email (Free, for members, one-on-one email help).

    We will update our website on a regular basis, with news, events, product launches and new content. We encourage our visitors to visit our website and sign up for our newsletter, the first issue of which will be released at the end of July. As this functionality shall be available within the next two weeks, please keep visiting our website: www.designscan.me.

    If you experience any problems using our website or if you have any suggestions, please contact us at marketing@designscan.me

     

    0 Comments

    Leave a comment › Posted in: Daily Sneak Peak

    1. Multi-Instance Node.js App in PaaS Using Redis Pub/Sub

      If you chose PaaS as hosting for your application, you probably had or will have this problem: Your app is deployed to small "containers" (known as dynos in Heroku, or gears in OpenShift) and you want to scale it. 

      In order to do so, you increase the number of containers—and every instance of your app is pretty much running in another virtual machine. This is good for a number of reasons, but it also means that the instances don't share memory. 

      In this tutorial I will show you how to overcome this little inconvenience.

      When you chose PaaS hosting, I assume that you had scaling in mind. Maybe your site already witnessed the Slashdot effect or you want to prepare yourself for it. Either way, making the instances communicate with each other is pretty simple.

      Keep in mind that in the article I will assume that you already have a Node.js app written and running.


      Step 1: Redis Setup

      First, you have to prepare your Redis database. I like to use Redis To Go, because the setup is really quick, and if you are using Heroku there is an add-on (although your account must have a credit card assigned to it). There is also Redis Cloud, which includes more storage and backups.

      From there, the Heroku setup is pretty easy: Select the add-on on the Heroku Add‑ons page, and select Redis Cloud or Redis To Go, or use one of the following commands (note that the first one is for Redis To Go, and the second one is for Redis Cloud):

      $ heroku addons:add redistogo 
      $ heroku addons:add rediscloud

      Step 2: Setting Up node_redis

      At this point, we have to add the required Node module to the package.json file. We will use the recommended node_redis module. Add this line to your package.json file, in the dependencies section:

      "node_redis": "0.11.x"

      If you want, you can also include hiredis, a high-performance library written in C, which node_redis will use if it's available:

      "hiredis": "0.1.x"

      Depending on how you created your Redis database and which PaaS provider you use, the connection setup will look a bit different. You need host, port, username, and password for your connection.

      Heroku

      Heroku stores everything in the config variables as URLs. You have to extract the information you need from them using Node's url module (config var for Redis To Go is process.env.REDISTOGO_URL and for Redis Cloud process.env.REDISCLOUD_URL). This code goes on the top of your main application file:

      var redis = require('redis'); 
      var url = require('url'); 
      
      var redisURL = url.parse(YOUR_CONFIG_VAR_HERE); 
      var client = redis.createClient(redisURL.host, redisURL.port); 
      
      client.auth(redisURL.auth.split(':')[1]); 

      Others

      If you created the database by hand, or use a provider other than Heroku, you should have the connection options and credentials already, so just use them:

      var redis = require('redis'); 
      var client = redis.createClient(YOUR_HOST, YOUR_PORT); 
      client.auth(YOUR_PASSWORD);

      After that we can start working on communication between instances.


      Step 3: Sending and Receiving Data

      The simplest example will just send information to other instances that you've just started. For example, you can display this information in the admin panel.

      Before we do anything, create another connection named client2. I will explain why we need it later.

      Let's start by just sending the message that we started. It's done using the publish() method of the client. It takes two arguments: the channel we want to send the message to, and the message's text:

      client.publish('instances', 'start'); 

      That's all you need to send the message. We can listen for messages in the message event handler (notice that we call this on our second client):

      client2.on('message', function (channel, message) {

      The callback is passed the same arguments that we pass to the publish() method. Now let's display this information in the console:

      if ((channel == 'instances') and (message == 'start')) 
          console.log('New instance started!'); 
      });

      The last thing to do is to actually subscribe to the channel we will use:

      client2.subscribe('instances');

      We used two clients for this because when you call subscribe() on the client, its connection is switched to the subscriber mode. From that point, the only methods you can call on the Redis server are SUBSCRIBE and UNSUBSCRIBE. So if we are in the subscriber mode we can publish() messages.

      If you want you can also send a message when the instance is being shut down—you can listen to the SIGTERM event and send the message to the same channel:

      process.on('SIGTERM', function () { 
          client.publish('instances', 'stop'); 
          process.exit(); 
      }); 

      To handle that case in the message handler add this else if in there:

      else if ((channel == 'instances') and (message == 'stop')) 
          console.log('Instance stopped!');

      So it looks like this afterwards:

      client2.on('message', function (channel, message) { 
      
          if ((channel == 'instances') and (message == 'start')) 
              console.log('New instance started!'); 
          else if ((channel == 'instances') and (message == 'stop')) 
              console.log('Instance stopped!'); 
      
      });

      Note that if you are testing on Windows, it does not support the SIGTERM signal.

      To test it locally, start your app a few times and see what happens in the console. If you want to test the termination message, don't issue the Ctrl+C command in the terminal—instead, use the kill command. Note that this is not supported on Windows, so you can't check it.

      First, use the ps command to check what id your process has—pipe it to grep to make it easier:

      $ ps -aux | grep your_apps_name 

      The second column of the output is the ID for which you are looking. Keep in mind that there will be also a line for the command you just ran. Now execute the kill command using 15 for the signal—it's SIGTERM:

      $ kill -15 PID

      PID is your process ID.


      Real-World Examples

      Now that you know how to use the Redis Pub/Sub protocol, you can go beyond the simple example presented earlier. Here are a few use-cases that may be helpful.

      Express Sessions

      This one is extremely helpful if you are using Express.js as your framework. If your application supports user logins, or pretty much anything that utilizes sessions, you will want to make sure the user sessions are preserved, no matter if the instance restarts, the user moves to a location that is handled by another one, or the user is switched to another instance because the original one went down.

      A few things to remember:

      • The free Redis instances will not suffice: you need more memory than the 5MB/25MB they provide.
      • You will need another connection for this.

      We will need the connect-redis module. The version depends on the version of Express you are using. This one is for Express 3.x:

      "connect-redis": "1.4.7"

      And this for Express 4.x:

      "connect-redis": "2.x"

      Now create another Redis connection named client_sessions. The usage of the module again depends on the Express version. For 3.x you create the RedisStore like this:

      var RedisStore = require('connect-redis')(express)

      And in 4.x you have to pass the express-session as the parameter:

      var session = require('express-session'); 
      var RedisStore = require('connect-redis')(session);

      After that the setup is the same in both versions:

      app.use(session({ store: new RedisStore({ client: client_sessions }), secret: 'your secret string' }));

      As you can see, we are passing our Redis client as the client property of the object passed to RedisStore's constructor, and then we pass the store to the session constructor.

      Now if you start your app, log in, or initiate a session and restart the instance, your session will be preserved. The same happens when the instance is switched for the user.

      Exchanging Data With WebSockets

      Let's say you have a completely separated instance (worker dyno on Heroku) for doing more resource-eating work like complicated calculations, processing data in the database, or exchanging a lot of data with an external service. You will want the "normal" instances (and therefore the users) to know the result of this work when it's done.

      Depending on whether you want the web instances to send any data to the worker, you will need one or two connections (let's name them client_sub and client_pub on the worker too). You can also reuse any connection that is not subscribing to anything (like the one you use for Express sessions) instead of the client_pub.

      Now when the user wants to perform the action, you publish the message on the channel that is reserved just for this user and for this specific job:

      // this goes into your request handler 
      client_pub.publish('JOB:USERID:JOBNAME:START', JSON.stringify(THEDATAYOUWANTTOSEND));
      client_sub.subscribe('JOB:USERID:JOBNAME:PROGRESS');

      Of course you'll have to replace USERID and JOBNAME with appropriate values. You should also have the message handler prepared for the client_sub connection:

      client_sub.on('message', function (channel, message) { 
      
          var USERID = channel.split(':')[1]; 
          
          if (message == 'DONE') 
              client_sub.unsubscribe(channel); 
          
          sockets[USERID].emit(channel, message); 
      
      });

      This extracts the USERID from the channel name (so make sure you don't subscribe to channels not related to user jobs on this connection), and sends the message to the appropriate client. Depending on which WebSocket library you use, there will be some way to access a socket by its ID.

      You may wonder how the worker instance can subscribe to all of those channels. Of course, you don't just want to do a few loops on all possible USERIDs and JOBNAMEs. The psubscribe() method accepts a pattern as the argument, so it can subscribe to all JOB:* channels:

      // this code goes to the worker instance 
      // and you call it ONCE 
      client_sub.psubscribe('JOB:*')

      Common Problems

      There are a few problems you may encounter when using Pub/Sub:

      • Your connection to the Redis server is refused. If this happens, make sure you provide proper connection options and credentials, and that the maximum number of connections has not been reached.
      • Your messages are not delivered. If this happens, check that you subscribed to the same channel you are sending messages on (seems silly, but sometimes happens). Also make sure that you attach the message handler before calling subscribe(), and that you call subscribe() on one instance before you call publish() on the other.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Creating Maintainable WordPress Meta Boxes: Save and Retrieve

      As we come up on the end of this series, we have two more topics to cover:

      1. Saving information to and retrieving information from the database
      2. Refactoring the code so that it becomes more maintainable for us

      In the previous article, we looked at validation, sanitization, and implementing this functionality for the elements that we've displayed on the front-end. In this article, we're going to continue the process by saving the information to the database, retrieving the information, and displaying it on the front-end.

      Along the way, we'll also look at some of the built-in WordPress API functions designed to help make this a bit easier for us as well as some tips for double-checking our work in the database to verify our information is being saved exactly as we expect.

      We've got just a bit more to go in order to bring this plugin to life, so let's get started.

      Saving Data

      In order to display data on the front-end, we obviously need to get it into the database first. Since we're working with meta boxes, then we can use functions that are available via the Meta Box API in order to save this information.

      Specifically, we're going to be working with the following functions:

      There is another function, add_post_meta, that is also available for writing information to the database; however, update_post_meta does the same thing if the data does not already exist in the database.

      Another question that I've seen come up when it comes to deleting post meta data is why? That is, why delete information rather than save an empty value? 

      You can argue this is a personal preference - and it is - but if you're working with an elaborate plugin that has a number of different fields, and the fields have no value, then it makes sense not to maintain an empty row.

      Furthermore, unless the absence of a value is meaningful for something on the user interface, then there's also no reason to maintain an empty value as we're allowing the database to more closely mirror the information that's being displayed on the screen. 

      Keeping the user interface, application layer code, and database as consistent as possible is helpful when trying to write maintainable code. 

      So with that said, let's look into the process of saving the fields for each of our input fields.

      1. Draft

      Recall from the previous post that the Draft tab contains a single textarea that is meant to be a place for authors to collect various notes and URLs from around the web that are relevant to the content they are preparing to publish.

      When we last left this code, we had the following:

      <?php
       
      // If the 'Drafts' textarea has been populated, then we sanitize the information.
      if ( ! empty( $_POST['authors-commentary-drafts'] ) ) {
       
          // We'll remove all white space, HTML tags, and encode the information to be saved
          $drafts = trim( $_POST['authors-commentary-drafts'] );
          $drafts = esc_textarea( strip_tags( $drafts ) );
       
          // More to come...
       
      }

      Here, we're looking to see if the content of the $_POST array is populated. If so, we then sanitize the information using trim and esc_textarea.

      At this point, we're ready to write it to the database so let's replace the line that reads // More to come... with the following code (note that we'll take a more in-depth look at the code after the block):

      <?php
          
      // If the 'Drafts' textarea has been populated, then we sanitize the information.
      if ( ! empty( $_POST['authors-commentary-drafts'] ) ) {
      
      	// We'll remove all white space, HTML tags, and encode the information to be saved
      	$drafts = trim( $_POST['authors-commentary-drafts'] );
      	$drafts = esc_textarea( strip_tags( $drafts ) );
      
      	update_post_meta( $post_id, 'authors-commentary-drafts', $drafts );
      
      } else {
      	
      	if ( '' !== get_post_meta( $post_id, 'authors-commentary-drafts', true ) ) {
      		delete_post_meta( $post_id, 'authors-commentary-drafts' );
      	}
      	
      }

      Here, we're using the update_post_meta function in order to add or update the content in the database. Note that the function takes three parameters:

      1. The post ID that is used in order to associate this information with the post
      2. A meta key that's used to uniquely identify the value
      3. The actual meta value associated with the meta key

      Notice also that if the value of the $_POST array is empty then we check to see if there is a value for the draft in the database and, if it exists, then we remove it.

      2. Resources

      Because we've already laid all of the ground work for sanitizing the information and we've seen how to both update and delete information in the database, doing the same for the Resources tab is more of the same.

      The one exception is that since we're dealing with a dynamic set of information, we need to dynamically associate the post with a unique ID based on how many resources we're saving.

      In the previous post, our code looked like this:

      <?php
      
      // If the 'Resources' inputs exist, iterate through them and sanitize them
      if ( ! empty( $_POST['authors-commentary-resources'] ) ) {
      
          $resources = $_POST['authors-commentary-resources'];
          foreach ( $resources as $resource ) {
      
      	    $resource = esc_url( strip_tags( $resource ) );
      
      	    // More to come...
      
          }
      
      }

      When it comes to dynamically processing information, a foreach loop works great; however, when saving information, we need to associate a unique key with each value. 

      One option would be to setup a for loop in order to suffix the meta key with a a unique key (by using the iterator for each value in the loop), but this can cause problems when it comes to deleting information. Specifically, if the user inputs a value for the first, second, and third input but then removes the second input leaving only the first and third when updating the post, we need to properly delete those empty values and shift all of the records accordingly.

      This can be done in a number of different ways, but it's actually easier to save a single serialized array to a unique index rather than try to do anything fancy with database rows, queries, and so on.

      As such, we update the code above to look like this:

      <?php
          
      // If the 'Resources' inputs exist, iterate through them and sanitize them
      if ( ! empty( $_POST['authors-commentary-resources'] ) ) {
      
      	$resources = $_POST['authors-commentary-resources'];
      	$sanitized_resources = array();
      	foreach ( $resources as $resource ) {
      
      		$resource = esc_url( strip_tags( $resource ) );
          	if ( ! empty( $resource ) ) {
      		    $sanitized_resources[] = $resource;
      		}
      
      	}
      	
      	update_post_meta( $post_id, 'authors-commentary-resources', $sanitized_resources );
      
      }
      

      If you peek into the database and look at this specific key, you should see something like this stored as the value:

      a:3:{i:0;s:22:"http://tommcfarlin.com";i:1;s:19:"http://tutsplus.com";i:2;s:17:"http://google.com";}

      We'll see how this plays out when we retrieve the information from the database later in this article. Note also that we need to account for the case when a user has removed all instances of resources.

      Just as we did in the first part of the article, we simply delete the post meta data if a value exists. This can be done using very similar code:

      <?php
          
      // If the 'Resources' inputs exist, iterate through them and sanitize them
      if ( ! empty( $_POST['authors-commentary-resources'] ) ) {
      
      	$resources = $_POST['authors-commentary-resources'];
      	$sanitized_resources = array();
      	foreach ( $resources as $resource ) {
      
      		$resource = esc_url( strip_tags( $resource ) );
      		$sanitized_resources[] = $resource;
      
      	}
      
      	update_post_meta( $post_id, 'authors-commentary-resources', $sanitized_resources );
      
      } else {
      
      	if ( '' !== get_post_meta( $post_id, 'authors-commentary-resources', true ) ) {
      		delete_post_meta( $post_id, 'authors-commentary-resources' );
      	}
      
      }

      Now we need to save the values for the last meta box.

      3. Published

      The final tab of the meta box, the Published tab, is going to be the easiest one for us to update as it pulls together everything we've looked at thus far in the article.

      Specifically, we're iterating through a collection of values, writing them to an array, and then serializing the array to the database. Perhaps the most important thing to note is that we're using an associative array and we're indexing each value by the value of the comment ID.

      As we'll see later in the article, this will make it much easier to set the values on the user interface.

      <?php
          
      // If there are any values saved in the 'Resources' input, save them
      if ( ! empty( $_POST['authors-commentary-comments'] ) ) {
      
      	$comments = $_POST['authors-commentary-comments'];
      	$sanitized_comments = array();
      	foreach ( $comments as $comment_id => $comment_value ) {
      
      		$comment = strip_tags( stripslashes( $comment_value ) );
      		$sanitized_comments[ $comment_id ] = $comment;
      
      	}
      	
      	update_post_meta( $post_id, 'authors-commentary-comments', $sanitized_comments );
      
      }

      Just as we did in the previous section, if there's nothing specified in the $_POST array, then we check the existence of the values in the database and, if they exist, we delete them:

      <?php
          
      // If there are any values saved in the 'Resources' input, save them
      if ( ! empty( $_POST['authors-commentary-comments'] ) ) {
      
      	$comments = $_POST['authors-commentary-comments'];
      	$sanitized_comments = array();
      	foreach ( $comments as $comment_id => $comment_value ) {
      
      		$comment = strip_tags( stripslashes( $comment_value ) );
      		$sanitized_comments[ $comment_id ] = $comment;
      
      	}
      	
      	update_post_meta( $post_id, 'authors-commentary-comments', $sanitized_comments );
      
      } else {
      
      	if ( '' !== get_post_meta( $post_id, 'authors-commentary-comments', true ) ) {
      		delete_post_meta( $post_id, 'authors-commentary-comments' );
      	}
      
      }

      As mentioned, this final example pulls everything together that we've seen for the last two tabs, so it should be relatively clear code to follow at this point.

      A Word About The Database

      Before going any further, let's take a moment to understand how we may end up querying information from the database. 

      Let's say you have a post with the ID of 9000 (yours will vary based on your setup). You can take that ID and look in the wp_postmeta table to see all of the meta information that's associated with the post.

      The Post Meta Data Table

      Furthermore, you can specify the key to pull back only the information associated with the post ID and key.

      If you only specify the post ID, you'll see all meta information associated with the post. If you specify only the key, then you'll see all post IDs that contain content for their drafts. If you specify both the post ID and the key, you'll pull back only the draft information that you've specified for a single post.

      Speaking of retrieving data, let's look at the steps necessary to display the post meta data in the dashboard of our plugin.

      Retrieving Data

      Now that all of the information has been saved to the database, we can introduce code that will retrieve it and display it in the proper tab of each plugin. The nice thing about this is that it will be using functions and constructors (like get_post_meta and for) that we've already been using.

      1. Draft

      Locate admin/views/partials/drafts.php. Assuming you've been following along with everything up to this point, the code should look like this:

      <div class="inside">
          <textarea id="authors-commentary-drafts" name="authors-commentary-drafts"></textarea>
      </div>

      To populate this textarea, we need to make a call to get_post_meta using the current post ID and the key that we used to save information earlier in this article. Take a look at the following code:

      <div class="inside">
          <textarea id="authors-commentary-drafts" name="authors-commentary-drafts"><?php echo get_post_meta( get_the_ID(), 'authors-commentary-drafts', true ); ?></textarea>
      </div>

      Note that we're passing in three parameters:

      1. The first is the post ID which is retrieved by using the get_the_ID function.
      2. The second is the key that we've specified when saving the data to uniquely identify it.
      3. The third is a boolean value true that's telling the function to return us the value as a string rather than in an array.

      If the value doesn't exist, then it simply returns an empty string so the textarea is empty.

      2. Resources

      For Resources, we make a similar call; however, this time we want to iterate through the results so that we can dynamically create the user interface.

      Because of the way WordPress serializes the array, we still want the information returned in a string format (though it will be a de-serialized array) that will allow us to use a foreach loop to iterate through it.

      <div class="inside hidden">
          <div id="authors-commentary-resources">
      		<?php $resources = get_post_meta( get_the_ID(), 'authors-commentary-resources', true ); ?>
      		<?php foreach ( $resources as $resource ) { ?>
      			<input type="text" value="<?php echo $resource; ?>" />
      		<?php } ?>
      	</div><!-- #authors-commentary-resources -->
      	<p><input type="submit" id="authors-commentary-add-resource" value="Add Resource" class="button" />
      </div>

      In short, we retrieve the information from the database, loop through it creating an input element for each value and then rendering it to the page. 

      This also allows us to remove elements by simply deleting a value and then updating the post. From there, the display will re-render itself such that there are no empty input elements.

      3. Published

      Arguably, this is the easiest part of the plugin. Since we've already got so much code in the template, the only thing we really need to do is determine if the value for the checkbox is set in the meta data array.

      Since we're using the comment ID as the numerical index of the array, we can simply check to see if the comment ID is contained in the array of meta keys that's returned from the meta data.

      Here's how:

      <div class="inside hidden">
          <?php $comments = $this->load_post_comments(); ?>
      	<ul id="author-commentary-comments">
      		<?php foreach ( $comments as $comment ) { ?>
      			<li>
      				<label for="authors-commentary-comment-<?php echo $comment->comment_ID ?>">
      					<?php $comments = get_post_meta( get_the_ID(), 'authors-commentary-comments', true ); ?>
      					<input type="checkbox" name="authors-commentary-comments[<?php echo $comment->comment_ID ?>]" id="authors-commentary-comment-<?php echo $comment->comment_ID ?>" <?php echo array_key_exists( $comment->comment_ID, $comments ) ? 'checked="checked"' : ''; ?> />
      					This comment has received a reply.
      				</label>
      				<p>
      					<em><?php echo $comment->comment_author; ?></em>:
      					<?php echo $comment->comment_content; ?>
      				</p>
      				<hr />
      			</li>
      		<?php } ?>
      	</ul>
      </div>

      Notice that we retrieve the value from the database, again passing true as the third value. 

      Next, we take the current comment ID and check to see if that value is contained in the array keys (by using array_key_exists) of the post meta data that was returned. If so, we mark the checkbox as checked; otherwise, we don't do anything.

      Up Next

      At this point, we have a fully functioning plugin that fulfills all of the requirements that we set out to build starting with the first article in the series.

      But is the plugin itself maintainable? That is, does it fulfill the primary objective of this series?

      In someways, yes but there is room for improvement. Since part of development has to do working with code that we inherit, we're going to take a look at how to refactor some of the code that we've written to make it easier to understand and more maintainable.

      Additionally, we'll be looking at reasons for why we're performing some of the refactoring that we're doing. After all, it wouldn't make much sense to simplify code or to move it around without any rationale.

      But before doing that, go ahead and work through this article and take a look at the code from the associated GitHub repository and leave any comments, questions, or general feedback below.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Creating a PayPal Buy Now Button With Variable Shortcodes

      PayPal is a great payment processor that allows anyone to send you money, which you can then send directly to your bank account. In this tutorial, you'll learn how to make a WordPress plugin allowing you to generate a Buy Now button, using a variable shortcode.

      The main shortcode will have a default value of $50 USD, with the Large size, though you'll be able to overwrite this every time you enter the shortcode; this is known as a variable shortcode. 

      So, let's get started!

      1. Initializing the Plugin

      Step 1

      Create a new directory in wp-content/plugins called paypal-buy-now-button-shortcode, and within that, create a file called paypal-buy-now-button-shortcode.php.

      Step 2

      In order for WordPress to know that this is a plugin, you need to add the following header information to the beginning of your new PHP file.

      <?php
      /**
       * Plugin Name: PayPal Buy Now Button Shortcode
       * Plugin URI: http://www.samberson.com
       * Description: A simple PayPal Buy Now button plugin with shortcode.
       * Version: 1.0.0
       * Author: Sam Berson
       * Author URI: http://www.samberson.com
       * License: GPL-3.0+
       * License URI: http://www.gnu.org/licenses/gpl-3.0.html
       * Domain Path: /lang
       * Text Domain: paypal-buy-now-button-shortcode
       */

      2. Creating the Shortcode

      Step 1

      You'll now begin by creating a new function with attributes, called paypal_buy_now_shortcode( $atts ), and opening up the function.

      /**
       * Generates the markup for the shortcode on the public site.
       */
      function paypal_buy_now_shortcode( $atts ) {

      Step 2

      Next, you'll set up the plugin's options, and add an array containing the default shortcode attributes.

      $options = get_option( 'paypal_buy_now_options' );
      
      $atts = shortcode_atts(
          array(
              'amount' => '50',
              'currency' => 'USD',
              'size' => 'SM'
          ),
          $atts
      );
      
      extract( $atts );

      Step 3

      You're now going to set the output for the front-end of the shortcode, which is a standard HTML form, with some PHP included in it, which will transmit the form data such as the PayPal ID, amount, currency, and button size. You'll also close off the new function, which you created before.

          return '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
                      <div class="paypal-donations">
                          <input type="hidden" name="cmd" value="_xclick">
                          <input type="hidden" name="business" value="' . $options['paypal_user_id'] . '">
                          <input type="hidden" name="amount" value="' . $amount . '">
                          <input type="hidden" name="rm" value="0">
                          <input type="hidden" name="currency_code" value="' . $currency . '">
                          <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_buynow_' . $size . '.gif" name="submit" alt="' . __( 'PayPal - The safer, easier way to pay online.', 'paypal-buy-now-button-shortcode' ) . '">
                          <img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
                      </div>
                  </form>';
      
      }

      Step 4

      Finally, you'll initialise the function as a shortcode by using the add_shortcode() function, which is built in to WordPress. Essentially, you're saying that the shortcode will be [buy_now], using the paypal_buy_now_shortcode function.

      add_shortcode( 'buy_now', 'paypal_buy_now_shortcode' );

      3. Adding More Functions

      Step 1

      Next, you'll add the paypal_buy_now_user_id function, and its options, which will allow an HTML input field to display in the back end.

      /**
       * Generates the markup for the PayPal user id.
       */
      function paypal_buy_now_user_id() {
      
          $options = get_option( 'paypal_buy_now_options' );
      
          echo "<input name='paypal_buy_now_options[paypal_user_id]' type='email' value='{$options['paypal_user_id']}'/>";
      }

      Step 2

      With the paypal_buy_now_register_settings function, you'll be registering the settings fields in the back end, and giving their data names. In this case, you're registering the settings, adding the section to the back end, and then initializing the PayPal Id field.

      /**
       * Registers settings page and fields.
       */
      function paypal_buy_now_register_settings() {
      
          register_setting( 'paypal_buy_now_settings', 'paypal_buy_now_options' );
      
          add_settings_section( 'paypal_buy_now_section', '', null, __FILE__ );
      
          add_settings_field( 'paypal_user_id', __( 'PayPal Id', 'paypal-buy-now-button-shortcode' ),'paypal_buy_now_user_id', __FILE__, 'paypal_buy_now_section' );
      }

      Step 3

      Similar to what you did earlier with the shortcode initialization, you're going to add the paypal_buy_now_register_settings function as an action in the admin area.

      add_action( 'admin_init', 'paypal_buy_now_register_settings' );

      4. Admin Options HTML

      Step 1

      The paypal_buy_now_options_page function will allow you to add the HTML required to display the form correctly in the back end. After adding the function, you'll create the HTML structure, with an opening div and h2, and then the form with the fields you initialized earlier.

      /**
       * Generates the markup for the options page.
       */
      function paypal_buy_now_options_page() {
      
          ?>
          <div class="wrap">
              <h2><?php _e( 'PayPal Buy Now Shortcode Settings', 'paypal-buy-now-button-shortcode' ); ?></h2>
              <form method="post" action="options.php" enctype="multipart/form-data">
                  <?php
      
                  settings_fields( 'paypal_buy_now_settings' );
      
                  do_settings_sections( __FILE__ );
      
                  ?>
                  <p class="submit">
                      <input type="submit" class="button-primary" name="submit" value="<?php _e( 'Save Changes', 'paypal-buy-now-button-shortcode' ); ?>">
                  </p>
              </form>
          </div>
          <?php
      
      }

      Step 2

      Now, the paypal_buy_now_add_settings_menu function will allow you to create a new menu / page in the back end, and define what the various titles should be.

      /**
       * Adds menu item to the settings.
       */
      function paypal_buy_now_add_settings_menu() {
      
          $title = __( 'PayPal Buy Now Shortcode', 'paypal-buy-now-button-shortcode' );
      
          add_options_page( $title, $title, 'administrator', __FILE__, 'paypal_buy_now_options_page');
      }
      
      add_action( 'admin_menu', 'paypal_buy_now_add_settings_menu' );

      5. Using the Plugin

      You've now successfully created the plugin, but how do you use it? Well, it's very simple.

      Step 1

      If you use the main shortcode on its own, like below, you'll see a large button, which when clicked will set the amount as $50 USD.

      [buy_now]

      Step 2

      You can then use the different attributes you set up to alter the button. So you can set the size to either small ('SM'), or large ('LG').

      [buy_now size=LG]

      Step 3

      Then, the currency code can be set as any of the recognised PayPal currencies, such as USD or GBP.

      [buy_now currency=GBP size=LG]

      Step 4

      Finally, you'll set the amount as a numerical value, such as 100, or 40. Remember not to include the currency symbol in the amount variable.

      [buy_now amount=150 currency=GBP size=LG]

      Step 5

      One final point I should make is that because there are default values set already, you don't need to set all three variables each time; you could simply change one or two of them, if need be.

      In Summary

      That's it! You've now created a new plugin which allows you to create a PayPal Buy Now button, using a variable shortcode. If you have any questions, please feel free to leave a comment below!

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Evaluating Your Business for a WordPress eCommerce Solution

      There is a general perception that WordPress is free and easy to set up, and that one can rapidly set up an online store and start trading. The truth of the matter is, there are a lot of considerations one has to think of first before setting up an online store.

      In this article, we will look at some of the general considerations and the functional and technical requirements of setting up a WordPress eCommerce website and eCommerce sites in general.

      General Considerations

      We shall look at all these components in order to find some direction on how to customize a WordPress eCommerce website that will run efficiently.

      Store Design

      Have you ever sat down and thought about how your store should look? Your general theme design may change depending on the WordPress plugin you're planning on integrating to implement your eCommerce site (we've looked at plugins in another article in this series). 

      It is important to consider the design of your store first before choosing any plugin. A product catalogue that has been poorly constructed can be very difficult to work with, both for the site owner and the customers. Products on the website should be well arranged and match the look and flow of the whole website. This makes it easier for customers to locate or even search for particular items.

      Cost of Setup

      How much are you willing to invest? Yes, one may reason that WordPress is free and even most eCommerce plugins are free, but when implementing an online shop you will realize that there are a lot of other functionalities that require you to spend some money.

      Even with the free plugins, they most of the time require very vital extensions and add-ons that turn out to be essential for the plugins to be of significance to the website. The plugin add-ons, hosting, SSL certificates, support and so on are all required in order to run an eCommerce site effectively.

      Responsive Design

      With many people using mobile devices to access websites, this should be a top consideration for any eCommerce site. The shopping cart should be responsive, allowing customers to purchase using any device that suites them. 

      There are a number of WordPress theme marketplaces that stock themes and that have eCommerce integrated in such a way that it works both on desktop and mobile devices, which makes it much easier to select a theme that is suitable for your site.

      Functional Requirements

      Product Type

      What sort of product are you planning on selling? Is it physical, digital downloads, or affiliate product links? Various WordPress eCommerce solutions are suited for diverse product types. 

      You should look at the type of merchandise you’re selling before choosing the platform that's suitable for your eCommerce site.

      Pricing Scenarios and Shipping

      Even though most WordPress eCommerce plugin developers have put a lot of consideration into possible pricing scenarios, you need to think about the various ways you will put up prices on your site. 

      When creating an online store, you may need to keep in mind the various properties used when deciding how to price, for example, or when grouping particular items. And if you have shipping services on your website, you need an eCommerce plugin that will be able to integrate with other services such as FedEx.

      Secure Payment Gateways

      Once you have figured out the various pricing and shipping configurations, the next thing that should come to mind is how customers will pay for goods bought from your site. 

      All WordPress eCommerce integrates one or more payment solutions. It’s up to you, the site owner, to decide on a payment platform that you think your customers will be comfortable using when they make payments. 

      SSL and General Protection

      Secure socket layer (SSL) helps encrypt important information shared by your clients on the website, for example credit card information. Using an SSL certificate on your website promotes a general sense of security and integrity. It’s a standard that has been accepted worldwide for website security.

      In case you plan on collecting credit data on your site, you need a solution that is PA-DSS (Payment Application Data Security Standard) compliant. This will permit you to collect credit card information from your clients.

      Technical Requirements

      Performance

      There are certain times when you install a plugin on a simple WordPress website and the site seems to be a bit slow. Now think of a scenario of implementing an eCommerce WordPress site. Most of the plugins are huge, require a lot of resources, and require a lot of memory to serve up the pages quickly.

      As your site grows and traffic increases, this will even get worse, so it's important you do not host your site on a shared hosting server. Simply avoid the headache by having your website either on a managed virtual private server, dedicated server, or dedicated WordPress hosting service.

      Scalability

      Scalability is about planning for the future. It's good to evaluate what you're currently selling on your site, and try and find out what will be the case a few years down the line when your products triple in number. You should at least be assured the WordPress platform you're using will support these scenarios later when your website gets more traffic.

      Summary

      We have highlighted some of the general considerations of setting up an eCommerce website. Some of them are WordPress specific, and others apply to all other available eCommerce platforms. 

      In the next article in this series, will look at the available plugins we have in WordPress, and their specific features.

       

      0 Comments

      Leave a comment › Posted in: Daily

  • Page 1 of 33 pages  1 2 3 >  Last ›
  • Browse the Blog

    Syndicate

    governing-bruise