Title: WP-Polls
Author: Lester Chan
Published: <strong>Январ 3, 2006</strong>
Last modified: Август 9, 2026

---

Search plugins

![](https://ps.w.org/wp-polls/assets/banner-772x250.png?rev=3639519)

![](https://ps.w.org/wp-polls/assets/icon.svg?rev=977996)

# WP-Polls

 By [Lester Chan](https://profiles.wordpress.org/gamerz/)

[Download](https://downloads.wordpress.org/plugin/wp-polls.3.0.0.zip)

 * [Details](https://tg.wordpress.org/plugins/wp-polls/#description)
 * [Reviews](https://tg.wordpress.org/plugins/wp-polls/#reviews)
 *  [Installation](https://tg.wordpress.org/plugins/wp-polls/#installation)
 * [Development](https://tg.wordpress.org/plugins/wp-polls/#developers)

 [Support](https://wordpress.org/support/plugin/wp-polls/)

## Description

WP-Polls adds a poll to your site: a question, its answers, and a result bar that
replaces the voting form once a visitor has voted, without a page reload. A poll
can go in a post with a shortcode or a block, in a sidebar with the widget, or anywhere
in your theme with a template tag.

A poll can accept one answer or several, close on a date you set, and be shown as
a form or as its result. The markup of every part of it is a template you can edit,
and the bars are styled with CSS custom properties your theme can override.

### Donations

I spent most of my free time creating, updating, maintaining and supporting these
plugins, if you really love my plugins and could spare me a couple of bucks, I will
really appreciate it. If not feel free to use it without any obligations.

### Usage

### Showing A Poll From A Theme

    ```
    <?php if ( function_exists( 'vote_poll' ) && ! in_pollarchive() ): ?>
        <li>
            <h2>Polls</h2>
            <ul>
                <li><?php get_poll();?></li>
            </ul>
            <?php display_polls_archive_link(); ?>
        </li>
    <?php endif; ?>
    ```

 * To show specific poll, use `<?php get_poll(2); ?>` where 2 is your poll id.
 * To show random poll, use `<?php get_poll(-2); ?>`
 * To embed a specific poll in your post, use `[poll id="2"]` where 2 is your poll
   id.
 * To embed a random poll in your post, use `[poll id="-2"]`
 * To embed a specific poll’s result in your post, use `[poll id="2" type="result"]`
   where 2 is your poll id.

### Showing A Poll In A Block

Two blocks are available in the editor, under **Widgets**:

 * **Poll** — one poll, as its voting form or as its result. Set **Poll ID** in 
   the sidebar, or leave it at zero for the current poll, which is what an empty`[
   poll]` does. **Show** chooses between the voting form and the result.
 * **Polls Archive** — every poll with its results, the same listing `[page_polls]`
   produces.

Both render on the server, so the block preview in the editor is the real poll rather
than an approximation, and changing a poll updates every post showing it without
re-saving anything.

**The shortcodes still work and are not going anywhere.** `[poll]`, `[poll=2]` and`[
page_polls]` behave exactly as they always have, and a post already containing one
needs no change. The blocks call the same code the shortcodes call, so the two render
identically — use whichever suits the post.

### Showing A Poll In A Widget

 1. Go to `WP-Admin -> Appearance -> Widgets`.
 2. Add the **Polls** widget to a widget area. On block themes the widget is under 
    the _Legacy Widget_ block, or in `Appearance -> Editor` if your theme has no widget
    areas at all.
 3. Set its title and which poll it shows, then save.
 4. Scroll down for instructions on how to create a Polls Archive.

### How To Add A Polls Archive?

 1. Go to `WP-Admin -> Pages -> Add New`.
 2. Type any title you like in the post’s title area.
 3. If you ARE using nice permalinks, after typing the title, WordPress will generate
    the permalink to the page. You will see an ‘Edit’ link just beside the permalink.
 4. Click ‘Edit’ and type in `pollsarchive` in the text field and click ‘Save’.
 5. Type `[page_polls]` in the post’s content area.
 6. Click ‘Publish’.

 * If you ARE NOT using nice permalinks, go to `WP-Admin -> Polls -> Settings` and
   fill in `Poll Archive URL`, under the `Archive` heading, with the URL of the 
   Polls Archive page you created above.

### To Display Total Polls

    ```
    <?php if ( function_exists( 'get_pollquestions' ) ): ?>
        <?php get_pollquestions(); ?>
    <?php endif; ?> 
    ```

### To Display Total Poll Answers

    ```
    <?php if ( function_exists( 'get_pollanswers' ) ): ?>
        <?php get_pollanswers(); ?>
    <?php endif; ?> 
    ```

### To Display Total Poll Votes

    ```
    <?php if ( function_exists( 'get_pollvotes' ) ): ?>
        <?php get_pollvotes(); ?>
    <?php endif; ?> 
    ```

### To Display Poll Votes by ID

    ```
    <?php if ( function_exists( 'get_pollvotes_by_id' ) ): ?>
        <?php get_pollvotes_by_id($poll_id); ?>
    <?php endif; ?>
    ```

### To Display Total Poll Voters

    ```
    <?php if ( function_exists( 'get_pollvoters' ) ): ?>
        <?php get_pollvoters(); ?>
    <?php endif; ?> 
    ```

### To Display Poll Time by ID and date format

    ```
    <?php if ( function_exists( 'get_polltime' ) ): ?>
        <?php get_polltime( $poll_id, $date_format ); ?>
    <?php endif; ?>
    ```

### WP-CLI

    ```
    wp polls list
    wp polls list --status=open
    wp polls get 3
    wp polls open 3
    wp polls close 3
    wp polls delete 3 --yes
    ```

    ```
    wp polls list --status=open --format=ids | xargs -n1 wp polls close closes every open poll one at a time.
    ```

### REST API

    ```
    GET  /wp-json/polls/v1/poll/<id>
    GET  /wp-json/polls/v1/poll/<id>/result
    POST /wp-json/polls/v1/poll/<id>/vote
    ```

Reading is public, because a poll is public. Voting takes the same `poll_<id>-nonce`
the rendered voting form already carries, passed as a `nonce` parameter, and is 
subject to the same eligibility and repeat-vote settings as voting through the page.

Each response carries the rendered markup as well as the numbers, because your templates
decide what a poll looks like and a client that rebuilt the markup itself would 
ignore them.

**A refusal answers 403**, not 400 — a closed poll, a vote already cast, a bad nonce,
nothing selected. 400 is kept for a parameter this plugin never had a chance to 
look at, and a poll that does not exist is 404. So a 403 means the request was understood
and the answer is no, and sending it again differently will not help.

**These routes are an addition.** The `admin-ajax.php` `polls` action is unchanged
and still supported.

### Translating the template

The plugin templates can be translated via template variables.
 There are these 
filters for the custom template variables

    ```
    wp_polls_template_voteheader_variables
    wp_polls_template_votebody_variables
    wp_polls_template_votefooter_variables
    wp_polls_template_resultheader_variables
    wp_polls_template_resultbody_variables
    wp_polls_template_resultfooter_variables
    ```

The Result Body (Voted) and Result Footer (Voted) templates are filtered by
 wp_polls_template_resultbody_variables
and `wp_polls_template_resultfooter_variables` too – the variables are shared, only
the markup filters are separate.

Add filter to your theme and register custom variable where you will add your translation.

Good practice is to name them for example with prefix `STR_` in the example `STR_TOTAL_VOTERS`.

    ```
        /**
         * Localize wp_polls_template_resultfooter_variables.
         *
         * @param array $variables An array of template variables.
         * @return array $variables Modified template variables.
         */
        function wp_polls_template_resultfooter_variables( $variables ) {

            // Add strings.
            $variables['%STR_TOTAL_VOTERS%'] = __( 'Total voters', 'theme-textdomain' );

            return $variables;
        }

    // Trigger the filter
    add_filter( 'wp_polls_template_resultfooter_variables', 'wp_polls_template_resultfooter_variables' , 10, 1 );
    ```

In the admin side just call the custom variable like so and the variable has been
translated in the front-end.
 %STR_TOTAL_VOTERS%’

## Screenshots

[⌊Polls -> Manage Polls, every poll with its voters, its dates and whether it is
open⌉⌊Polls -> Manage Polls, every poll with its voters, its dates and whether it
is open⌉[

Polls -> Manage Polls, every poll with its voters, its dates and whether it is open

[⌊Add Poll: the question, its answers, when it closes, and how many answers a voter
may pick⌉⌊Add Poll: the question, its answers, when it closes, and how many answers
a voter may pick⌉[

Add Poll: the question, its answers, when it closes, and how many answers a voter
may pick

[⌊Poll Settings: the bar, the sort order, who may vote, and how a repeat vote is
spotted⌉⌊Poll Settings: the bar, the sort order, who may vote, and how a repeat 
vote is spotted⌉[

Poll Settings: the bar, the sort order, who may vote, and how a repeat vote is spotted

[⌊The Templates tab, holding the markup of the poll, of its results and of the archive⌉⌊
The Templates tab, holding the markup of the poll, of its results and of the archive⌉[

The Templates tab, holding the markup of the poll, of its results and of the archive

[⌊A poll in a post, waiting for a vote⌉⌊A poll in a post, waiting for a vote⌉[

A poll in a post, waiting for a vote

[⌊The polls archive, every poll with what people said⌉⌊The polls archive, every 
poll with what people said⌉[

The polls archive, every poll with what people said

[⌊The Poll block in the editor: the preview is the real poll, and the sidebar picks
which poll and whether to show the voting form or the result⌉⌊The Poll block in 
the editor: the preview is the real poll, and the sidebar picks which poll and whether
to show the voting form or the result⌉[

The Poll block in the editor: the preview is the real poll, and the sidebar picks
which poll and whether to show the voting form or the result

## Blocks

This plugin provides 2 blocks.

 *   Polls Archive Every poll, with its results, as an archive.
 *   Poll A poll, as a voting form or as its result.

## Installation

 1. Install and activate the plugin.
 2. Create your first poll at `WP-Admin -> Polls -> Add Poll`.
 3. Show it: type `[poll]` into a post, add the **Poll** block, add the **Polls** widget
    to a sidebar, or call `get_poll()` from your theme. Usage below covers all four.
 4. Templates, the bar, who may vote and how a repeat vote is spotted are all at `WP-
    Admin -> Polls -> Settings`.

## FAQ

### Everyone can vote as many times as they like

Check **Settings -> Header That Contains The IP**. If it names a header such as

HTTP_X_FORWARDED_FOR, make sure the proxy in front of WordPress always overwrites
that header. Anything a visitor can set themselves can be changed on every request,
and WP-Polls has no way to tell a real proxy from a forged header.

Before 3.0.0 WP-Polls also used the entire header value as the voter’s identity.

X-Forwarded-For is a list, `client, proxy1, proxy2`, so a visitor could append one
more entry and count as somebody new. It now reads only the first address in the
list.

If you are not behind a proxy, leave the setting blank.

### Every voter is logged with the same IP, or the wrong one

WordPress is behind a proxy or a CDN and every request reaches it from the proxy’s

address. Name the header your proxy sets under **Settings -> Header That Contains
The IP — `HTTP_CF_CONNECTING_IP` for Cloudflare — or, to trust the usual set of 
proxy headers without naming one, add this to `wp-config.php`:

    ```
    define( 'WP_POLLS_TRUST_PROXY', true );
    ```

Sites that need to decide per request can use the `wp_polls_trust_proxy` filter,
which
 defaults to that constant.

### Poll logs show a hashed IP rather than an address

That is deliberate and unchanged: WP-Polls stores `wp_hash()` of the address, so
the
 logs can tell two voters apart without keeping their IP addresses.

### My poll bars lost their styling, or my customised result template came back

3.0.0 rebuilt the poll bar. It used to be one `<div class="pollbar">` sized by an

inline width; it is now a track holding a fill:

    ```
    <div class="wp-polls-bar" aria-hidden="true"><div class="wp-polls-bar-fill" style="width: 42%;"></div></div>
    ```

The **Result Body** and **Result Body (Voted)** templates are rewritten to that 
markup
 on upgrade, _including customised ones_. There was no way to keep them: 
the class names and the stylesheet changed with the markup, so a customised copy
of the old template would have rendered a bar with no rules left to match it. Re-
apply your changes on **Poll Templates**, keeping the two `wp-polls-bar` elements.

If you re-add a bar by hand, use `%POLL_ANSWER_PERCENTAGE%` for the width.
 %POLL_ANSWER_IMAGEWIDTH%
was removed in 3.0.0 and is no longer substituted, so a template still containing
it emits the literal token into the `style` attribute and the bar renders with no
width at all.

If your theme ships its own `wp-polls.css`, the bar rules are not in it — they used
to
 be generated by PHP into an inline `<style>` block, and they now live in the
plugin’s stylesheet. Either copy the `.wp-polls-bar` rules across, or delete your
copy and override these instead, which is the supported way now:

    ```
    .wp-polls {
        --wp-polls-bar-height: 8px;
        --wp-polls-bar-background: #d8e1eb;
        --wp-polls-bar-border: #c8c8c8;
        --wp-polls-bar-radius: 3px;
    }
    ```

### Why doesn’t my poll’s answers add up to 100%?

 * It is because of rounding issues. To make it always round up to 100%, the last
   poll’s answer will get the remainding percentage added to it. To enable this 
   feature, add this to your theme’s functions.php: `add_filter( 'wp_polls_round_percentage','
   __return_true' );`

### How Does WP-Polls Load CSS?

 * WP-Polls will load `wp-polls.css` from your theme’s directory if it exists.
 * If it does not exist, it loads the `css/wp-polls.css` that ships with WP-Polls.
 * This will allow you to upgrade WP-Polls without worrying about overwriting your
   polls styles that you have created.
 * A theme copy made before 3.0.0 has no poll bar rules in it, because they used
   to be generated by PHP. See _My poll bars lost their styling_ above.

### How Do I Have Individual Colors For Each Poll’s Bar?

 * Courtesy Of [TreedBox.com](https://treedbox.com)
 * Set `--wp-polls-bar-background` on the answer rather than styling the bar itself.
   The bar reads that custom property, so this works whichever poll bar style is
   configured, and it keeps working if the markup changes again.
 * Add to the end of your `wp-polls.css`:

    ```
    .wp-polls-ul li:nth-child(01) { --wp-polls-bar-background: #8fa0c5; }
    .wp-polls-ul li:nth-child(02) { --wp-polls-bar-background: #ffff88; }
    .wp-polls-ul li:nth-child(03) { --wp-polls-bar-background: #ff8a3b; }
    .wp-polls-ul li:nth-child(04) { --wp-polls-bar-background: #a61e2a; }
    .wp-polls-ul li:nth-child(05) { --wp-polls-bar-background: #4ebbff; }
    .wp-polls-ul li:nth-child(06) { --wp-polls-bar-background: #fbca54; }
    .wp-polls-ul li:nth-child(07) { --wp-polls-bar-background: #aad34f; }
    .wp-polls-ul li:nth-child(08) { --wp-polls-bar-background: #66cc9a; }
    .wp-polls-ul li:nth-child(09) { --wp-polls-bar-background: #98cbcb; }
    .wp-polls-ul li:nth-child(10) { --wp-polls-bar-background: #a67c52; }
    .wp-polls-ul li:hover { --wp-polls-bar-background: #ff0000; }
    .wp-polls .wp-polls-bar-fill { transition: background-color 0.7s ease-in-out; }
    ```

Before 3.0.0 this was written against `.pollbar`, the single element the bar used
to
 be. That class no longer exists, so the old snippet colours nothing.

## Reviews

![](https://secure.gravatar.com/avatar/e568a48fa12155130c23116d7be303764dca7638a7257f79507e1528954fd0f7?
s=60&d=retro&r=g)

### 󠀁[Thanks for the plugin and a suggestion](https://wordpress.org/support/topic/thanks-for-the-plugin-and-a-suggestion/)󠁿

 [joel05](https://profiles.wordpress.org/joel05/) Сентябр 27, 2025

This plugin is perfect. Thank you so much to the creators. The only thing that I
miss is being able to make anonymous polls, so I would like to be able to activate
an option in the poll for anonymous polls, in which the logs show all the votes 
together, without indicating what option each person has voted for.

![](https://secure.gravatar.com/avatar/76e56af37dbb9acd68eb7f218690807399384e9ffe79a100833efa7026bf3ad7?
s=60&d=retro&r=g)

### 󠀁[Awesome work!](https://wordpress.org/support/topic/awesome-work-150/)󠁿

 [Zeljko Jagust](https://profiles.wordpress.org/zjagust/) Май 22, 2024

For the ones who know something about HTML and CSS syntax, this plugin is perfect!
It does exactly what is needed regarding polls, while the looks can be fully customized.
IMHO, a brilliant piece of work!

![](https://secure.gravatar.com/avatar/b386455620084633756983fc57b321d21ecfcba3a1be005259e7fd0fc9c5fce6?
s=60&d=retro&r=g)

### 󠀁[Used for long time, now got a problem](https://wordpress.org/support/topic/used-for-long-time-now-got-a-problem/)󠁿

 [Dani](https://profiles.wordpress.org/daniw42/) Апрел 29, 2023

Hi there, I’ve been using this plugin and loved it for its simplicity alongside 
with the ability to customize the look and feel. Somehow, at some point, the admin
interface changed and I am now able to see the answers of all users. Before, I was
only able to see how many users voted for each answer, not who. This is a major 
problem for me. Is there any way to hide the usernames from the answers given? I
need to see which users voted, but not what answer they gave. The answers should
only be seen as a total for each option. Thanks

![](https://secure.gravatar.com/avatar/02b3df1cb95d3eac280f2a76c166cef531ca595427851155fbc424cf19f64c5e?
s=60&d=retro&r=g)

### 󠀁[Nice feature set, doesn’t work with cache](https://wordpress.org/support/topic/nice-feature-set-doesnt-work-with-cache/)󠁿

 [expirator](https://profiles.wordpress.org/expirator/) Октябр 21, 2022

Love the feature set, easy to use, great to work with, but it fails with my cache
setup (standard Cloudflare) setup. Have to remove it a site and move to another 
solution, sadly this was after my install, setting up on my custom post types, etc.
Would love to see it updated in the future.

![](https://secure.gravatar.com/avatar/4dffc932532d29fddfdd3918d64e0b20c3206c568c90d7359df749a53f80b9f2?
s=60&d=retro&r=g)

### 󠀁[Excellent](https://wordpress.org/support/topic/excellent-12039/)󠁿

 [redima](https://profiles.wordpress.org/redima/) Июл 23, 2022

Excellent, easy going plugin. Thank you.

![](https://secure.gravatar.com/avatar/290933bdd0a253ba0036e5fc61dc9bb1e7c95d589406270ba0a69aeb6a9a1fb9?
s=60&d=retro&r=g)

### 󠀁[Only one question](https://wordpress.org/support/topic/only-one-question/)󠁿

 [astrodates](https://profiles.wordpress.org/astrodates/) Март 23, 2022

You can have unlimited answers, but only one question?

 [ Read all 136 reviews ](https://wordpress.org/support/plugin/wp-polls/reviews/)

## Contributors & Developers

“WP-Polls” is open source software. The following people have contributed to this
plugin.

Contributors

 *   [ Lester Chan ](https://profiles.wordpress.org/gamerz/)

“WP-Polls” has been translated into 16 locales. Thank you to [the translators](https://translate.wordpress.org/projects/wp-plugins/wp-polls/contributors)
for their contributions.

[Translate “WP-Polls” into your language.](https://translate.wordpress.org/projects/wp-plugins/wp-polls)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/wp-polls/), check out
the [SVN repository](https://plugins.svn.wordpress.org/wp-polls/), or subscribe 
to the [development log](https://plugins.trac.wordpress.org/log/wp-polls/) by [RSS](https://plugins.trac.wordpress.org/log/wp-polls/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

### 3.0.0

 * FIXED: The limit on how many answers a vote may select was enforced in the browser
   and nowhere else, so one crafted request could vote for every answer of a single-
   choice poll — each answer gaining a vote and the poll’s total gaining several,
   while the voter count went up by one. That leaves the percentages, `%POLL_MOST_ANSWER%`
   and `%POLL_LEAST_ANSWER%` permanently wrong. The maximum is checked on the server
   now, on both the AJAX and REST paths
 * NEW: A `wp polls` WP-CLI command — `list`, `get`, `open`, `close` and `delete`.
 * NEW: A `polls/v1` REST API for reading a poll, reading its result and voting.
   The `admin-ajax.php` `polls` action is unchanged and still supported.
 * NEW: Two editor blocks, **Poll** and **Polls Archive**, both under Widgets. They
   render on the server through the same code the shortcodes use, so a block and
   a shortcode showing the same poll produce the same markup. The `[poll]`, `[poll
   =2]` and `[page_polls]` shortcodes are unchanged and still supported — nothing
   needs converting, and posts already containing them keep working.
 * BREAKING: Requires WordPress 6.8 and PHP 8.2, up from 6.0 and 7.4.
 * BREAKING: The scripts no longer define any global JavaScript functions. `poll_vote()`,`
   poll_result()`, `poll_booth()` and the admin equivalents are now private, so 
   custom templates or themes that called them directly must move to `data-poll-
   id` / `data-poll-action` attributes. WP-Polls converts the stock templates for
   you on upgrade and warns in wp-admin about any it could not convert.
 * CHANGED: Options, templates, settings, the widget and the install/upgrade routine
   moved into classes under `includes/`. The documented extension points are unchanged:
   every `wp_polls_*` filter and action, both the `[poll]` and `[page_polls]` shortcodes,
   and the template tags keep their exact names and signatures.
 * CHANGED: The thirty-odd separate `wp_options` rows are now a single `wp_polls_options`
   row holding a nested array. Your settings are migrated automatically on upgrade;
   the old rows are removed once they have been folded in.
 * FIXED: XSS in the Poll Templates screen. Inline `onclick` handlers are replaced
   by `data-poll-action` / `data-poll-id` attributes and `onclick` is no longer 
   an allowed attribute in poll templates.
 * FIXED: On multisite, uninstall called `restore_current_blog()` once after the
   loop rather than once per site. `switch_to_blog()` pushes onto a stack, so the
   stack was left unwound by every site but the first.
 * FIXED: On uninstall the three poll tables were dropped from inside the loop over
   option rows, so the drop ran 36 times per site and issued three `DROP TABLE` 
   statements each instead of three in total.
 * CHANGED: Uninstall asks `get_sites()` for IDs only rather than hydrating a `WP_Site`
   object per site, and its table-dropping helper is now prefixed `wp_polls_uninstall_site()`
   instead of occupying the unprefixed global name `plugin_uninstalled()`.
 * FIXED: Network activating on multisite was a fatal error. The activation routine
   called `wp_get_sites()`, which WordPress removed in 5.1.
 * FIXED: On multisite the three poll tables were not registered with `$wpdb`, so
   any query made inside `switch_to_blog()` read and wrote the wrong site’s polls.
 * FIXED: Adding or removing a poll answer in wp-admin no longer breaks. It called
   jQuery’s `.size()`, which was removed in jQuery 3.
 * FIXED: The poll bar tooltip showed a literal `&amp;` for any answer containing
   an ampersand. The polls archive had its own copy of the same bug in `%POLL_ANSWER_TEXT%`,
   which is fixed too.
 * FIXED: Poll Logs had the same double encoding: an answer containing an ampersand
   showed a literal `&amp;` in both the answer filter and the log table.
 * FIXED: Voters identified by the comment author cookie were logged with a backslash
   before any apostrophe, so a commenter named `O'Brien` appeared in Poll Logs as`
   O\'Brien`.
 * FIXED: `$_SERVER['REMOTE_ADDR']` is no longer read unguarded, which warned under
   WP-CLI and cron on PHP 8.
 * FIXED: The result and vote links no longer follow their placeholder `href` when
   clicked.
 * FIXED: Removed the duplicated shortcode registration.
 * FIXED: Undefined array key warnings on missing stats_display options.
 * FIXED: Warnings when rendering a poll whose ID no longer exists.
 * FIXED: The voting endpoint read `$_REQUEST['view']` without checking it was set,
   which warned on PHP 8 for any request that left it out.
 * FIXED: Activation looked for `wp-admin/upgrade-functions.php`, which WordPress
   removed in 2.x, and stopped with an error message if it found neither that nor
   the current file.
 * FIXED: Poll Options could offer a poll bar style that saving then rejected, reverting
   it while still reporting «Settings saved.» The screen and the sanitiser now build
   the list of available styles the same way.
 * FIXED: Every stylesheet, script and image URL was built from a hardcoded `wp-
   polls/` path, so renaming the plugin directory left WP-Polls loading none of 
   its own assets. All paths now come from the plugin file itself.
 * CHANGED: Poll Options and Poll Templates now use the WordPress Settings API instead
   of hand-rolled form handling. Every row on both screens is registered with `add_settings_section()`
   and `add_settings_field()` and rendered by `do_settings_sections()`, so the screens
   look and behave like the rest of wp-admin and neither one writes any table markup
   of its own.
 * CHANGED: Poll Bar Background and Poll Bar Border are colour pickers now – the
   browser’s own colour input, the same control WP-Postratings uses – rather than
   six character text fields with a `#` printed beside them and a swatch kept in
   step by JavaScript. The bar preview follows the colour as it is picked. The setting
   is still stored as the six digits without the `#`, so a theme or filter reading
   it sees what it always did; a three digit value left over from 2.x is expanded
   to six on the way out, because a colour input will not display `#abc`.
 * CHANGED: Manage Polls is now a `WP_List_Table`, so it paginates at 20 polls a
   page, sorts on ID, Total Voters and Start Date, and puts Edit, Logs and Delete
   in hover row actions instead of three columns of links. The poll the site is 
   currently showing is still highlighted.
 * CHANGED: Add Poll, Edit Poll and Poll Logs are built out of the standard wp-admin
   furniture – `form-table` rows with real labels, `submit_button()`, `notice` messages,
   and one `h1` per screen – rather than tables laid out with `width`, `valign` 
   and `align` attributes. The Cancel buttons are links back to Manage Polls instead
   of a `history.go(-1)` that could not be middle-clicked or opened in a new tab.
 * FIXED: The stats under Manage Polls were accumulated while printing rows, which
   would have counted only the page being looked at once the list paginated. They
   are summed in SQL now.
 * FIXED: Opening the logs of a poll that allows multiple answers raised four undefined
   variable warnings: that filter’s fields were only initialised inside the branch
   that handles its own submission.
 * FIXED: The poll logs named their answers from a list built while printing the
   filter dropdown, so with the `wp_polls_log_show_log_filter` filter turned off
   every group heading in the log was blank. A vote recorded against no answer at
   all also warned instead of printing «Null Votes».
 * FIXED: Rows in the by-voter poll log never alternated: the row counter was reset
   inside the loop rather than at each new voter.
 * FIXED: Changing «Expiry Time For Cookie And Log» did not reschedule the cron 
   job. The callback that rebuilds the schedule was registered while the Poll Options
   screen rendered, but the save happens on `options.php`, which never loads that
   screen.
 * CHANGED: Removed every remaining inline `onclick`/`onblur`/`onchange` handler
   from the admin pages in favour of `data-poll-action` attributes and delegated
   listeners, so poll questions and answers no longer have to be escaped into a 
   JavaScript context.
 * CHANGED: Dropped the jQuery dependency. Both scripts, the inline admin scripts
   and the TinyMCE plugin now use the browser’s own APIs, so WP-Polls no longer 
   forces jQuery to load on the front end.
 * CHANGED: The scripts ship as readable source; the `.dev.js` copies have been 
   removed.
 * FIXED: The `polls-admin` AJAX handler now checks the `manage_polls` capability
   instead of relying on its nonces for authorisation.
 * FIXED: Escaped the poll bar colours, the voting form action and `%POLL_RESULT_URL%`
   on output, and validated the poll bar colours on save.
 * BREAKING: «Poll Logging Method» is now «Check For Repeat Votes», and it no longer
   decides whether anything is logged. It never did anything but choose what a returning
   visitor is matched against, and the two readings pointed opposite ways: a site
   that picked «Do Not Log» or «Logged By Cookie» got no vote log, no rows on the
   Logs screen and no WP-Stats figures, which is not what either choice sounds like.**
   Every vote is now recorded whatever this is set to.** The choices read «Do Not
   Check», «Check By Cookie», «Check By IP Address», «Check By Cookie And IP Address»
   and «Check By Username»; the stored numbers are unchanged, so your setting means
   what it always meant. The option key inside `wp_polls_options` is `check_method`
   rather than `logging_method`, migrated automatically. Sites that would rather
   not keep the record can return false from the new `wp_polls_log_vote` filter;
   the answer tallies and poll totals are columns on the poll tables and are updated
   either way.
 * BREAKING: «Expiry Time For Cookie And Log» is now «Remember A Voter For», and
   its hint no longer says the opposite of what the setting does. It offered «0 
   to disable»; zero disables nothing, it is what makes the block permanent — a 
   cookie lasting a year and no time limit at all on the IP and username queries.
   Nothing expires in the sense of being deleted either: the poll log keeps every
   vote whatever this says. All it decides is how far back a repeat-vote check looks.
   The value is unchanged, so existing sites behave exactly as before.
 * BREAKING: The «Polls AJAX Style» settings are gone. They chose whether to show
   a loading indicator and whether to fade the poll while a vote was in flight. 
   Telling somebody their vote is being processed is feedback rather than decoration,
   so the indicator now always shows; and whether to animate is the visitor’s answer
   rather than the site owner’s, so the fade follows `prefers-reduced-motion` like
   the spinner and the result bars already did. `poll_ajax_style` is dropped on 
   upgrade rather than carried.
 * BREAKING: The poll bar has been rebuilt and the change is applied on upgrade.
   It was one `<div class="pollbar">` sized by an inline width; it is now a `wp-
   polls-bar` track holding a `wp-polls-bar-fill`, which is what lets a 100% answer
   render at a true 100%. The Result Body and Result Body (Voted) templates are 
   rewritten to the new markup on upgrade **even if you had customised them** – 
   the class names and the stylesheet moved with the markup, so a customised copy
   of the old template has no rules left to match it. Re-apply your changes on Poll
   Templates. See the FAQ.
 * BREAKING: The poll bar rules moved out of the PHP-generated inline `<style>` 
   block and into `css/wp-polls.css`. Only four custom properties are emitted inline
   now – `--wp-polls-bar-height`, `--wp-polls-bar-background`, `--wp-polls-bar-border`
   and `--wp-polls-bar-image` – and overriding those is the supported way to restyle
   the bar. If your theme ships its own `wp-polls.css`, the bar rules are not in
   it; see the FAQ.
 * BREAKING: The `images/default` and `images/default_gradient` poll bar tiles are
   gone. The two shaded styles were 1px wide GIFs that carried their own colours,
   so picking one silently discarded the Poll Bar Background setting. Poll Bar Style
   is now Flat or Gradient, both drawn in CSS from the colour you configure. `default`
   and `default_gradient` become Gradient on upgrade, and the old «Use CSS Style»
   becomes Flat.
 * FIXED: A poll answer with every vote drew a 99% bar, and in the polls archive
   every bar drew at 90% of its real percentage, so the same answer was a visibly
   different length in the two places. Both fudges existed to stop the old bar’s
   border overflowing its container and are no longer needed.
 * FIXED: An answer with no votes drew a 1% sliver of a bar rather than an empty
   one.
 * FIXED: The polls archive applied the `wp_polls_round_percentage` rounding buffer
   unconditionally while the poll itself only applied it when the filter was turned
   on, so on a default install the same poll reported one set of percentages on 
   the page and a different set in the archive. The archive now honours the filter,
   which defaults to off. If you relied on archive percentages summing to exactly
   100, add `add_filter( 'wp_polls_round_percentage', '__return_true' );` to turn
   it back on — it now applies in both places.
 * FIXED: With the `wp_polls_round_percentage` filter enabled, the last answer’s
   printed percentage gets a rounding buffer added so the column sums to 100. The
   bar width was calculated before that happened, so the last answer printed one
   number and drew a different one. Every bar now matches the percentage beside 
   it.
 * BREAKING: The `%POLL_ANSWER_IMAGEWIDTH%` template variable has been removed and
   is no longer substituted. It only ever held the percentage with a fudge applied
   so the old bar’s border did not overflow, and with the fudges gone it said nothing`%
   POLL_ANSWER_PERCENTAGE%` does not. Use `%POLL_ANSWER_PERCENTAGE%` instead. The
   upgrade rewrites both result templates, so you only need to act if you re-customise
   them afterwards.
 * CHANGED: The poll bar no longer carries a `title` tooltip repeating the percentage
   and vote count that are already printed beside it, and is marked `aria-hidden`
   so screen readers do not read those numbers twice. On Result Body (Voted) the«
   You Have Voted For This Choice» tooltip moves onto the answer text itself.
 * CHANGED: The bar fill animates in, and honours `prefers-reduced-motion`.
 * CHANGED: `wp-polls-rtl.css` has been removed. `css/wp-polls.css` now uses CSS
   logical properties, so the one stylesheet lays out correctly in both directions
   and right-to-left sites load one file fewer. If your theme overrides `wp-polls-
   rtl.css`, fold those rules into your `wp-polls.css`.
 * BREAKING: If you set «Header That Contains The IP», WP-Polls used the whole header
   as the voter’s identity. `X-Forwarded-For` is a chain the visitor controls the
   left of, so appending one more hop produced a different identity and another 
   vote. It now takes the first valid address in the header, and falls back to `
   REMOTE_ADDR` when the header holds no address at all. Sites that left the setting
   blank are unaffected and their existing vote logs still match. See the FAQ.
 * CHANGED: Added the `WP_POLLS_TRUST_PROXY` constant and the `wp_polls_trust_proxy`
   filter, matching WP-Email and WP-UserOnline, so sites behind Cloudflare or a 
   load balancer can opt in to the usual proxy headers without naming one on the
   settings screen. Proxy headers are still ignored unless you opt in.
 * CHANGED: Reformatted to the WordPress Coding Standards. Fifteen translatable 
   strings gained numbered placeholders (`%1$s`), which changes their msgid, so 
   those strings need retranslating.
 * BREAKING: The settings row is named `wp_polls_options` rather than `poll_options`,
   and the two version markers `poll_version` and `poll_db_version` collapse into
   one `wp_polls_version` row holding `plugin` and `db`. All three old rows are 
   folded in and removed on upgrade.
 * BREAKING: Poll Options and Poll Templates are two tabs of one **Polls -> Settings**
   screen instead of two menu entries. Their URLs change from `admin.php?page=wp-
   polls/polls-options.php` and `…/polls-templates.php` to `admin.php?page=wp-polls-
   settings&tab=options` and `&tab=templates`, and Manage Polls and Add Poll move
   to `admin.php?page=wp-polls` and `?page=wp-polls-add`.
 * BREAKING: WP-Polls no longer reads or writes WP-Stats’ shared `stats_display`
   row. Whether the polls block appears on the WP-Stats page is now a WP-Polls setting,
   under **WP-Polls -> Settings -> WP-Stats**, and WP-Polls contributes its block
   through the `wp_stats_sections` filter. Update all seven WP-Stats plugins together.
 * BREAKING: Every class is prefixed `WP_Polls_`: `Polls_Options` is `WP_Polls_Options`,`
   Polls_Display` is `WP_Polls_Display`, `Polls_Vote` is `WP_Polls_Vote`, `Polls_Settings`
   is `WP_Polls_Settings`, `Polls_Install` is `WP_Polls_Install`, `Polls_Widget`
   is `WP_Polls_Widget`, `Polls_List_Table` is `WP_Polls_List_Table`, `Polls_Templates`
   is `WP_Polls_Template` and `Polls_Core` is plain `WP_Polls`. The template tags,
   the shortcodes and every `wp_polls_*` hook are unchanged.
 * NEW: `WP_POLLS_DB_VERSION` alongside `WP_POLLS_VERSION`, and a `wp_polls_capability`
   filter over the `manage_polls` check.
 * CHANGED: The plugin files are laid out the way every other plugin here is: the
   five loose screens move into `includes/`, the stylesheets into `css/` and the
   scripts into `js/`, named after the plugin. A theme overriding `polls-css.css`
   should rename its copy `wp-polls.css`.
 * CHANGED: The localised script objects are `wpPollsL10n` and `wpPollsAdminL10n`,
   replacing `pollsL10n` and `pollsAdminL10n`.
 * CHANGED: The loading indicator is drawn in CSS instead of loading `images/loading.
   gif`, so it inherits the theme’s colour, scales with the font size and stops 
   animating for a visitor who has asked for reduced motion. `images/` is gone.
 * CHANGED: No wp-admin screen carries an inline `style` attribute any more: status
   messages use core’s `notice` classes and anything that starts hidden uses core’s`.
   hidden` class.
 * CHANGED: The front end stylesheet sets no font and no text colour, and its hardcoded
   blues, blacks and whites become `currentColor` plus the `--wp-polls-border` and`--
   wp-polls-surface` custom properties, so a poll is legible on a dark theme without
   a second stylesheet.
 * CHANGED: The two inline `<script>` blocks the settings screens carried – the 
   poll bar preview and the Restore Default Template buttons – moved into `js/wp-
   polls-admin.js`.
 * FIXED: `current_time( 'timestamp' )`, which WordPress deprecated, is replaced
   by `WP_Polls::now()`. Poll times are still stored as site-local, so nothing shifts.
 * NOTE: Every filter and action WP-Polls fires now carries a docblock recording
   what it is passed and which release introduced it.
 * FIXED: The «maximum number of choices allowed» alert ended in a trailing space
   inside the translated string, and the script added a space of its own — so the
   number was preceded by two. The space belongs to the script, which is the same
   in every language

## Meta

 *  Version **3.0.0**
 *  Last updated ** 6 соат ago**
 *  Active installations **40,000+**
 *  WordPress version ** 6.8 or higher **
 *  Tested up to **7.0.3**
 *  PHP version ** 8.2 or higher **
 *  Languages
 * [Arabic](https://ar.wordpress.org/plugins/wp-polls/), [Bulgarian](https://bg.wordpress.org/plugins/wp-polls/),
   [Chinese (China)](https://cn.wordpress.org/plugins/wp-polls/), [Czech](https://cs.wordpress.org/plugins/wp-polls/),
   [Danish](https://da.wordpress.org/plugins/wp-polls/), [Dutch](https://nl.wordpress.org/plugins/wp-polls/),
   [English (US)](https://wordpress.org/plugins/wp-polls/), [French (France)](https://fr.wordpress.org/plugins/wp-polls/),
   [German](https://de.wordpress.org/plugins/wp-polls/), [Hungarian](https://hu.wordpress.org/plugins/wp-polls/),
   [Portuguese (Brazil)](https://br.wordpress.org/plugins/wp-polls/), [Russian](https://ru.wordpress.org/plugins/wp-polls/),
   [Spanish (Chile)](https://cl.wordpress.org/plugins/wp-polls/), [Spanish (Spain)](https://es.wordpress.org/plugins/wp-polls/),
   [Spanish (Venezuela)](https://ve.wordpress.org/plugins/wp-polls/), [Turkish](https://tr.wordpress.org/plugins/wp-polls/),
   and [Ukrainian](https://uk.wordpress.org/plugins/wp-polls/).
 *  [Translate into your language](https://translate.wordpress.org/projects/wp-plugins/wp-polls)
 * Tags
 * [ajax](https://tg.wordpress.org/plugins/tags/ajax/)[poll](https://tg.wordpress.org/plugins/tags/poll/)
   [polls](https://tg.wordpress.org/plugins/tags/polls/)[survey](https://tg.wordpress.org/plugins/tags/survey/)
   [vote](https://tg.wordpress.org/plugins/tags/vote/)
 *  [Advanced View](https://tg.wordpress.org/plugins/wp-polls/advanced/)

## Ratings

 4.2 out of 5 stars.

 *  [  93 5-star reviews     ](https://wordpress.org/support/plugin/wp-polls/reviews/?filter=5)
 *  [  15 4-star reviews     ](https://wordpress.org/support/plugin/wp-polls/reviews/?filter=4)
 *  [  4 3-star reviews     ](https://wordpress.org/support/plugin/wp-polls/reviews/?filter=3)
 *  [  4 2-star reviews     ](https://wordpress.org/support/plugin/wp-polls/reviews/?filter=2)
 *  [  20 1-star reviews     ](https://wordpress.org/support/plugin/wp-polls/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/wp-polls/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/wp-polls/reviews/)

## Contributors

 *   [ Lester Chan ](https://profiles.wordpress.org/gamerz/)

## Support

Issues resolved in last two months:

     0 out of 1

 [View support forum](https://wordpress.org/support/plugin/wp-polls/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://lesterchan.net/site/donation/)