Example: Polls Extension

The best way to learn how to do anything is to actually do it, so let’s get get our hands dirty and create a polling extension called “Sidebar Polls”. It’s a simple extension letting users vote on polls you can add with a custom widget. The extension itself isn’t as important as the procedure so let’s take it one step at a time.

File and Folder Structure

Make the extension folder

In your runway-framework/extensions folder create a new folder named polls.

Add the file structure

In your runway-framework/extensions/polls folder create three new files:

  • load.php
  • object.php
  • settings-object.php

load.php

At the top of load.php add the information header:

<?php
/*
  Extension Name: Sidebar Polls
  Version: 0.9
  Description: Polls, an example of making a custom Runway extension.
  Author: Parallelus
  Author URI: http://para.llel.us  
*/

Save your load.php file and in your dashboard go to Runway > Extensions you will see it in the list of available extensions.

The main file must contain the header comment above for Runway to recognize this file.

object.php

Create the new Poll_Object() class, extending the core Runway_Object(), in the object.php file:

<?php
// Poll object (loaded on admin and public)
class Poll_Object extends Runway_Object{

}
?>

settings-object.php

Create the new Poll_Admin_Object() class, extending the core Runway_Admin_Object(), in the settings-object.php file:

<?php
// Poll admin object (loaded on admin only)
class Poll_Admin_Object extends Runway_Admin_Object{

}
?>

Note: We’ve chosen load.php, object.php and settings-object.php as our default file names but this is not required. Any naming convention may be used provided the references to the files are correct and the top of your main PHP file contains the extension information header. This header allows Runway to recognize the extension and without it your extension will not be detected.

Integration with Runway

Configuring the extension

You can save time using functionality already built into Runway such as generating admin pages, admin menus, creating forms and accessing data. To use these features you must register the extension with Runway.

To register the extension you need to provide some basic information to Runway. Inside the load.php file, we need to create the following settings array:

$settings = array(
  'name' => 'Sidebar Polls',                   // The extension name
  'option_key' => $shortname.'sidebar_polls',  // The key, a unique database ID 
  'parent_menu' => 'settings',                 // Extension parent menu
  'file' => __FILE__,                          // The path to the load.php file
);

Next we reference the extension classes in the files object.php and settings-object.php:

// Required components
include('object.php');
$poll_object = new Poll_Object($settings);

// Load admin components
if (is_admin()) {   
  include('settings-object.php');
  $poll_admin_object = new Poll_Admin_Object($settings);
}

The load.php file is now completed and so in your admin dashboard you can go to Runway > Extensions and activate the “Sidebar Polls” extension, after which you will see a Sidebar Polls item appear in the Settings menu.

The complete load.php file

The completed load.php file should now look like this:

<?php 
/*
  Extension Name: Sidebar Polls
  Version: 0.9
  Description: Polls, an example of making a custom Runway extension.
  Author: Parallelus
  Author URI: http://para.llel.us  
*/

$settings = array(
  'name' => 'Sidebar Polls',                   // The extension name
  'option_key' => $shortname.'sidebar_polls',  // The key, a unique database ID 
  'parent_menu' => 'settings',                 // Extension parent menu
  'file' => __FILE__,                          // The path to the load.php file
);

// Required components
include('object.php');
$poll_object = new Poll_Object($settings);

// Load admin components
if (is_admin()) {   
  include('settings-object.php');
  $poll_admin_object = new Poll_Admin_Object($settings);
}

?>

The settings-object.php file

This file holds the main admin object and is responsible for performing the save and edit actions along with other admin specific features. We’ve already created the file and defined the empty Poll_Admin_Object() class. Now it’s time to add some functionality.

The full Poll_Admin_Object() class is shown here. Update the class to match the code below.

// Poll admin object (loaded on admin only)
class Poll_Admin_Object extends Runway_Admin_Object{

  // Add actions
  function add_actions() {
    // Init action
    add_action( 'init', array( $this, 'init' ) );
  }

  function init() {

    // Get the saved poll data
    $this->poll_list = get_option( $this->option_key );

    // Get the navigation parameter
    if ( isset( $_REQUEST['navigation'] ) && !empty( $_REQUEST['navigation'] ) ) {
      $this->navigation = $_REQUEST['navigation'];
    }

    // Get the action parameter
    if ( isset( $_REQUEST['action'] ) && !empty( $_REQUEST['action'] ) ) {
      $this->action = $_REQUEST['action'];
    }

  }

  // Update poll data
  public function update_poll( $options = array() ) {

    if ( !empty( $options ) ) {
      $this->poll_list[$options['alias']] = $options;
      update_option( $this->option_key, $this->poll_list );
    }
  }

  // Delete poll
  public function delete_poll( $alias = null ) {
    if ( $alias != null && isset( $this->poll_list[$alias] ) ) {
      unset( $this->poll_list[$alias] );
      update_option( $this->option_key, $this->poll_list );
    }
  }

}

This section of code includes references to the navigation and action query string parameters, as well as functions for updating and deleting polls from the database. Navigation parameters are used to determine which page to load in the admin screen. The action parameter is specific to triggering functionality such as updating poll data or adding new polls to the database.

The update_poll() and delete_poll() functions do exactly what their names suggest, update or add polls to the database and delete existing polls.

The final piece of the settings-object.php file is to insert the code for the “Add New” button in the admin header. This is the button next to the title which loads the new poll screen for creating a new poll. We need to insert the code for the button immediately after the end of the Poll_Admin_Object() class. Add the code below to the end of the settings-object.php file:

// "Add New" button in admin page title
function poll_title_buttons_add_new( $title ) {
  $page       = ( isset( $_GET['page'] ) ) ? $_GET['page'] : '';
  $navigation = ( isset( $_GET['navigation'] ) ) ? $_GET['navigation'] : '';
  $add_new    = 'add_poll';

  if ( $page == 'widget-polls'  && $navigation != $add_new) {
    $title .= ' <a href="?page='.$page.'&navigation='.$add_new.'" class="add-new-h2">'. __( 'Add New', 'framework' ) .'</a>';
  }

  return $title;
}
add_filter( 'framework_admin_title', 'poll_title_buttons_add_new' );

The completed settings-object.php file

This finishes the settings-object.php file. The full file contents as they should be now can be seen below:

<?php

// Poll admin object (loaded on admin only)
class Poll_Admin_Object extends Runway_Admin_Object{

  // Add actions
  function add_actions() {
    // Init action
    add_action( 'init', array( $this, 'init' ) );
  }

  function init() {

    // Get the saved poll data
    $this->poll_list = get_option( $this->option_key );

    // Get the navigation parameter
    if ( isset( $_REQUEST['navigation'] ) && !empty( $_REQUEST['navigation'] ) ) {
      $this->navigation = $_REQUEST['navigation'];
    }

    // Get the action parameter
    if ( isset( $_REQUEST['action'] ) && !empty( $_REQUEST['action'] ) ) {
      $this->action = $_REQUEST['action'];
    }

  }

  // Update poll data
  public function update_poll( $options = array() ) {

    if ( !empty( $options ) ) {
      $this->poll_list[$options['alias']] = $options;
      update_option( $this->option_key, $this->poll_list );
    }
  }

  // Delete poll
  public function delete_poll( $alias = null ) {
    if ( $alias != null && isset( $this->poll_list[$alias] ) ) {
      unset( $this->poll_list[$alias] );
      update_option( $this->option_key, $this->poll_list );
    }
  }

}

// "Add New" button in admin page title
function poll_title_buttons_add_new( $title ) {
  $page       = ( isset( $_GET['page'] ) ) ? $_GET['page'] : '';
  $navigation = ( isset( $_GET['navigation'] ) ) ? $_GET['navigation'] : '';
  $add_new    = 'add_poll';

  if ( $page == 'widget-polls'  && $navigation != $add_new) {
    $title .= ' <a href="?page='.$page.'&navigation='.$add_new.'" class="add-new-h2">'. __( 'Add New', 'framework' ) .'</a>';
  }

  return $title;
}
add_filter( 'framework_admin_title', 'poll_title_buttons_add_new' );

?>

The object.php file

This file contains the Poll_Object() and handles all functions needing to be loaded on the public and admin side. It should be reserved for functions that require access in both areas of the site and those only used by the public features. Any admin only functions should be stored to the settings-object.php file.

We’ve already created the file and defined the empty Poll_Object() class. Now it’s time to add the functionality. First we can insert the content of the Poll_Object() class, this will include some references to the poll widget used for displaying the polls on your website.

// Poll object (loaded on admin and public)
class Poll_Object extends Runway_Object{

  public $poll_list, $option_key;

  public function __construct( $settings ) {
    parent::__construct( $settings );

    $this->option_key = $settings['option_key'];
    $this->poll_list = get_option( $this->option_key );

    add_action( 'widgets_init', array( $this, 'poll_widget_register' ) ); // function to load my widget
  }

  // Vote function
  public function vote( $poll = null, $vote = null ) {
    if ( $poll != null && $vote != null ) {
      $this->poll_list[$poll]['answers'][$vote]++;
      update_option( $this->option_key, $this->poll_list );
    }
  }

  // Register poll widget
  public function poll_widget_register() {
    register_widget( 'Poll_Widget' );
  }

}

Immediately following the Poll_Object() we need to add our widget class. This can be pasted directly into the object.php following the Poll_Object().

// Poll widget
class Poll_Widget extends WP_Widget {

  function __construct() {

    // Widget setup
    $widget_ops = array( 'classname' => 'poll-widget', 'description' => 'Description to my poll widget' );
    $this->WP_Widget( 'poll', 'Poll Widget', $widget_ops );

    // Handle the voting
    add_action( 'init', array( $this, 'user_poll' ) );
  }

  function user_poll() {
    global $poll_object, $just_voted;
    $just_voted = false;
    if ( isset( $_POST['poll_result'] ) && isset( $_POST['widget_alias'] ) ) {
      if ( !isset( $_COOKIE[$_POST['widget_alias']] ) ) {
        $poll_object->vote( $_POST['widget_alias'], $_POST['poll_result'] );
        setcookie( $_POST['widget_alias'], 1, time()+1209600 );
        $just_voted = $_POST['widget_alias'];
      }
    }
  }

  function widget( $args, $instance ) {
    global $poll_object, $just_voted;

    $poll =  ( isset( $instance['poll'] ) ) ? esc_attr( $instance['poll'] ) : 'none';
    extract( $args, EXTR_SKIP );
    echo $before_widget;
    echo $before_title;
    echo ( $poll != 'none' ) ? $poll_object->poll_list[$poll]['name'] : __( 'Poll', 'framework' );
    echo $after_title;

    if ( !isset( $_COOKIE[$poll] ) && $just_voted != $poll ) {
      ?>
      <form action="http://<?php echo  $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; ?>" method="post">
        <?php

        if ( $poll != 'none' ) {
          foreach ( $poll_object->poll_list[$poll]['variants'] as $key => $value ): ?>
            <div>
              <label for="variant-<?php echo $key; ?>">
                <input type="radio" name="poll_result" id="variant-<?php echo $key; ?>" value="<?php echo $key; ?>">
                <?php echo $value; ?>
              </label>
            </div><br>
            <?php 
          endforeach; ?>
          
          <input type="hidden" name="widget_alias" value="<?php echo $poll; ?>">
          <?php
        } else {
          _e( 'Please, select a poll in widget settings.', 'framework' );
        }
        ?>
        <input type="submit" value="<?php _e( 'Vote', 'framework' ); ?>">
      </form>
      <?php
    } else {
      if ( count( $poll_object->poll_list[$poll]['variants'] ) > 1 ) {
        echo "<ul style='list-style: none;'>";
        foreach ( $poll_object->poll_list[$poll]['variants'] as $key => $value ) {
          $answers = $poll_object->poll_list[$poll]['answers'];
          $count   = $answers[$key];
          $percent = (array_sum($answers)) ? $count / array_sum($answers) * 100 : 0;
          echo '<li>';
          echo '<div><b>'.$value.'</b>: &nbsp;'.$count.' '. __( 'votes', 'framework' ) .'</div>';
          echo '<div style="width:100%;border:1px solid #aaa;"><div style="height:8px;background-color:#ccc;width:'.$percent.'%"></div></div>';
          echo '</li>';
        }
        echo "</ul>";
      }
    }

    echo $after_widget;

  }

  function update( $new_instance, $old_instance ) {
    $updated_instance = $new_instance;
    return $updated_instance;
  }

  function form( $instance ) {
    global $poll_object;

    $poll = ( isset( $instance['poll'] ) ) ? esc_attr( $instance['poll'] ) : 'none';
    ?>
    <p>
      <label for="<?php echo $this->get_field_id( 'poll' ); ?>">
        <?php _e( 'Select The Poll:' ); ?> <br>
        <select id="<?php echo $this->get_field_id( 'poll' ); ?>" name="<?php echo $this->get_field_name( 'poll' ); ?>" >
          <option value="none" <?php echo ( $poll == 'none' ) ? 'selected="true"' : ''; ?>>None</option>
          <?php foreach ( $poll_object->poll_list as $key => $value ): ?>
            <option value="<?php echo $value['alias']; ?>" <?php echo ( $poll == $value['alias'] ) ? 'selected="true"' : ''; ?>><?php echo $value['name']; ?></option>
          <?php endforeach; ?>
        </select>
      </label>
    </p>
    <?php
  }

}

With the object.php file now completed we have a functional polls widget in Appearance > Widgets which we can deploy by dragging it into any widget-ready sidebar area; choose which poll to display from the drop-down menu.

The completed object.php file

This finishes the object.php file. The full file contents as they should be now can be seen below:

<?php

// Poll object (loaded on admin and public)
class Poll_Object extends Runway_Object{

  public $poll_list, $option_key;

  public function __construct( $settings ) {
    parent::__construct( $settings );

    $this->option_key = $settings['option_key'];
    $this->poll_list = get_option( $this->option_key );

    add_action( 'widgets_init', array( $this, 'poll_widget_register' ) ); // function to load my widget
  }

  // Vote function
  public function vote( $poll = null, $vote = null ) {
    if ( $poll != null && $vote != null ) {
      $this->poll_list[$poll]['answers'][$vote]++;
      update_option( $this->option_key, $this->poll_list );
    }
  }

  // Register poll widget
  public function poll_widget_register() {
    register_widget( 'Poll_Widget' );
  }

}

// Poll widget
class Poll_Widget extends WP_Widget {

  function __construct() {

    // Widget setup
    $widget_ops = array( 'classname' => 'poll-widget', 'description' => 'Description to my poll widget' );
    $this->WP_Widget( 'poll', 'Poll Widget', $widget_ops );

    // Handle the voting
    add_action( 'init', array( $this, 'user_poll' ) );
  }

  function user_poll() {
    global $poll_object, $just_voted;
    $just_voted = false;
    if ( isset( $_POST['poll_result'] ) && isset( $_POST['widget_alias'] ) ) {
      if ( !isset( $_COOKIE[$_POST['widget_alias']] ) ) {
        $poll_object->vote( $_POST['widget_alias'], $_POST['poll_result'] );
        setcookie( $_POST['widget_alias'], 1, time()+1209600 );
        $just_voted = $_POST['widget_alias'];
      }
    }
  }

  function widget( $args, $instance ) {
    global $poll_object, $just_voted;

    $poll =  ( isset( $instance['poll'] ) ) ? esc_attr( $instance['poll'] ) : 'none';
    extract( $args, EXTR_SKIP );
    echo $before_widget;
    echo $before_title;
    echo ( $poll != 'none' ) ? $poll_object->poll_list[$poll]['name'] : __( 'Poll', 'framework' );
    echo $after_title;

    if ( !isset( $_COOKIE[$poll] ) && $just_voted != $poll ) {
      ?>
      <form action="http://<?php echo  $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; ?>" method="post">
        <?php

        if ( $poll != 'none' ) {
          foreach ( $poll_object->poll_list[$poll]['variants'] as $key => $value ): ?>
            <div>
              <label for="variant-<?php echo $key; ?>">
                <input type="radio" name="poll_result" id="variant-<?php echo $key; ?>" value="<?php echo $key; ?>">
                <?php echo $value; ?>
              </label>
            </div><br>
            <?php 
          endforeach; ?>
          
          <input type="hidden" name="widget_alias" value="<?php echo $poll; ?>">
          <?php
        } else {
          _e( 'Please, select a poll in widget settings.', 'framework' );
        }
        ?>
        <input type="submit" value="<?php _e( 'Vote', 'framework' ); ?>">
      </form>
      <?php
    } else {
      if ( count( $poll_object->poll_list[$poll]['variants'] ) > 1 ) {
        echo "<ul style='list-style: none;'>";
        foreach ( $poll_object->poll_list[$poll]['variants'] as $key => $value ) {
          $answers = $poll_object->poll_list[$poll]['answers'];
          $count   = $answers[$key];
          $percent = (array_sum($answers)) ? $count / array_sum($answers) * 100 : 0;
          echo '<li>';
          echo '<div><b>'.$value.'</b>: &nbsp;'.$count.' '. __( 'votes', 'framework' ) .'</div>';
          echo '<div style="width:100%;border:1px solid #aaa;"><div style="height:8px;background-color:#ccc;width:'.$percent.'%"></div></div>';
          echo '</li>';
        }
        echo "</ul>";
      }
    }

    echo $after_widget;

  }

  function update( $new_instance, $old_instance ) {
    $updated_instance = $new_instance;
    return $updated_instance;
  }

  function form( $instance ) {
    global $poll_object;

    $poll = ( isset( $instance['poll'] ) ) ? esc_attr( $instance['poll'] ) : 'none';
    ?>
    <p>
      <label for="<?php echo $this->get_field_id( 'poll' ); ?>">
        <?php _e( 'Select The Poll:' ); ?> <br>
        <select id="<?php echo $this->get_field_id( 'poll' ); ?>" name="<?php echo $this->get_field_name( 'poll' ); ?>" >
          <option value="none" <?php echo ( $poll == 'none' ) ? 'selected="true"' : ''; ?>>None</option>
          <?php foreach ( $poll_object->poll_list as $key => $value ): ?>
            <option value="<?php echo $value['alias']; ?>" <?php echo ( $poll == $value['alias'] ) ? 'selected="true"' : ''; ?>><?php echo $value['name']; ?></option>
          <?php endforeach; ?>
        </select>
      </label>
    </p>
    <?php
  }

}

?>

Admin Interface

Default admin file, admin.php

By default a Runway extension will look for a file named admin.php when it is loaded inside the WordPress admin screen. This applies to any extension registered with the Runway core and extending the Runway_Admin_Object.

You can set a specific file to load your extension’s WP admin interface using the settings_file parameter for the $settings array in load.php. Below is an example to define polls.php instead of admin.php:

$settings = array(
  'name' => 'Sidebar Polls',                   // The extension name
  'option_key' => $shortname.'sidebar_polls',  // The key, a unique database ID 
  'parent_menu' => 'settings',                 // Extension parent menu
  'file' => __FILE__,                          // The path to the load.php file
  'settings_file' => 'polls.php',              // The admin PHP file loaded by WP
);

Because we’re not defining a custom admin file we know the admin.php file, the default, is our starting point for displaying the admin options.

In this file the contents of $this->navigation defines which which view or which event should be called. Also, the $this->action variable responsible for the additional operations is available here.

Below is the code for the extension’s admin.php file.

<?php

// Get some variables
$poll_name     = ( isset( $_REQUEST['name'] ) && !empty( $_REQUEST['name'] ) ) ? $_REQUEST['name'] : '';
$alias         = ( isset( $_REQUEST['alias'] ) && !empty( $_REQUEST['alias'] ) ) ? $_REQUEST['alias'] : sanitize_title( $poll_name );
$poll_variants = ( isset( $_REQUEST['variants'] ) && !empty( $_REQUEST['variants'] ) ) ? $_REQUEST['variants'] : '';
$poll_answers  = ( isset( $this->poll_list[$alias]['answers'] ) ) ? $this->poll_list[$alias]['answers'] : array();
$options       = ( isset( $_POST ) ) ? $_POST : array();

// Additional actions of our extension
switch ( $this->action ) {
  case 'update_poll':
    if ( !empty( $poll_name ) && !empty( $poll_variants ) ) {

      $options['alias'] = $alias;
      $answers = $poll_answers;
      
      foreach ( $options['variants'] as $key => $value ) {
        if ( !isset( $answers[$key] ) ) {
          $answers[$key] = 0;
        }
      }

      $options['answers'] = $answers;
      $this->update_poll( $options );
    }
    break;

  default:
    // nothing to do
  break;
}

// Managing of extension's navigation
switch ( $this->navigation ) {
  case 'add_poll':
    include 'views/poll-form.php';
    break;

  case 'edit_poll':
    include 'views/poll-form.php';
    break;

  case 'delete_poll':
    $this->delete_poll( $alias );
    include 'views/admin-home.php';
    break;

  case 'show_results':
    include 'views/show-results.php';
    break;

  default:
    include 'views/admin-home.php';
    break;
}

?>

The admin.php file calls up three settings pages or “views” – admin-home.php, poll-form.php, show-results.php – and below is the code for these files:

polls/views/admin-home.php

<p><?php _e('Create simple user polls and insert them into sidebars. Go to "Appearance > Widgets" and use the "Poll Widget" to display a poll.', 'framework'); ?></p>
<table class="wp-list-table widefat plugins">
  <thead>
    <tr>
      <th id="poll-name" class="manage-column column-name"><?php _e('Name', 'framework') ?></th>
      <th id="variants-count" class="manage-column column-header"><?php _e('Options', 'framework') ?></th>      
      <th id="answers-count" class="manage-column column-header"><?php _e('Responses', 'framework') ?></th>      
      <th id="actions" class="manage-column column-header"><?php _e('Actions', 'framework') ?></th>      
    </tr>
  </thead>
  <tbody id="the-list">  
    <?php

    // Show each poll question
    if(!empty($this->poll_list)) :
      foreach ((array) $this->poll_list as $poll) : 
        ?>
        <tr calss="active">
          <td class="column-name">
            <?php echo $poll['name']; ?>
          </td>
          <td class="column-alias">
            <?php echo count($poll['variants']); ?>
          </td>
          <td class="column-alias">
            <?php echo array_sum($poll['answers']); ?>
          </td>
          <td class="column-alias">
            <a href="<?php echo $this->self_url('edit_poll'); ?>&alias=<?php echo $poll['alias']; ?>"><?php _e('Edit', 'framework'); ?></a> |
            <a href="<?php echo $this->self_url('delete_poll'); ?>&alias=<?php echo $poll['alias']; ?>"><?php _e('Delete', 'framework'); ?></a>|
            <a href="<?php echo $this->self_url('show_results'); ?>&alias=<?php echo $poll['alias']; ?>"><?php _e('Show Results', 'framework'); ?></a>
          </td>
        </tr>      
        <?php 
      endforeach;
    else : ?>  
      <tr calss="active">
        <td class="no-items" colspan="2">
          <?php _e('No polles have been created.', 'framework'); ?>
        </td>      
      </tr>      
      <?php 
    endif;  
    ?>
  </tbody>
</table>

polls/views/poll-form.php

<form action="<?php echo $this->self_url(''); ?>&action=update_poll<?php echo !empty($alias) ? '&alias='.$alias : ''; ?>" id="add-field" method="post">
  <table class="form-table">
    <tbody>
      <tr class="">
        <th scope="row" valign="top">
          <?php _e('Question', 'framework'); ?>        
          <p class="description required"><?php _e('Required', 'framework'); ?></p>
        </th>
        <td class="vars">
          <input class="input-text " id="name" type="text" name="name" value="<?php echo (!empty($alias)) ? $this->poll_list[$alias]['name'] : ''; ?>">
          <p class="description"><?php _e('The question to be asked.', 'framework'); ?></p>
        </td>
      </tr>
      <tr class="">
        <th scope="row" valign="top">
          <?php _e('Answers', 'framework'); ?>
          <p class="description required"><?php _e('Required', 'framework'); ?></p>
        </th>        
        <td>
          <?php 
          if(!empty($alias)):
            foreach ($this->poll_list[$alias]['variants'] as $value): ?>
              <p class="variant">
                <input class="input-text" id="name" type="text" name="variants[]" value="<?php echo "$value"; ?>">
              </p>
              <?php 
            endforeach;
          else: ?>
            <p class="variant">
              <input class="input-text" id="name" type="text" name="variants[]" value="">
            </p>
            <?php 
          endif; 
          ?>
          <p>
            <input id="add_variant" type="button" class="button" value="<?php _e('Add Answer', 'framework'); ?>">
          </p>
        </td>
      </tr>
    </tbody>
  </table>
<input class="button-primary" type="submit" id="save-button" value="<?php _e('Save Settings', 'framework') ?>">
</form>
<script type="text/javascript">
(function($){
  $('#add_variant').click(function(e){

    variant = $('<input/>', {        
      class:  'input-text',
      type:   'text',
      name:   'variants[]',
      css: {
        'display': 'block'
      }              
    }).insertAfter('p.variant:last').wrap('<p class="variant"></p>');

    $(variant).focus();
  });
})(jQuery);
</script>

polls/views/show-results.php

<?php 

if(isset($alias)){
  echo "<h3>{$poll_object->poll_list[$alias]['name']}</h3>";
  if(count($this->poll_list[$alias]['variants']) > 1){
        echo "<ul style='list-style: none;'>";
    foreach ($this->poll_list[$alias]['variants'] as $key => $value){
      $answers = $this->poll_list[$alias]['answers'];
      $count   = $answers[$key];
      $percent = (array_sum($answers)) ? $count / array_sum($answers) * 100 : 0;
      echo '<li>';
      echo '<div><b>'.$value.'</b>: &nbsp;'.$count.' '. __( 'votes', 'framework' ) .'</div>';
      echo '<div style="width:300px;border:1px solid #aaa;"><div style="height:8px;background-color:#ccc;width:'.$percent.'%"></div></div>';
      echo '</li>';
    }
    echo "</ul>";
  }
}

?>

The Sidebar Polls extension is finished!

Download the full Sidebar Polls extension.

Create a Note

Google+