A content type, workflow, and Volto block for conducting online polls in Plone, for anonymous and logged-in users.
- Polls as content. A Poll asks one question with two or more options, and can hold the images it shows.
- Single or multiple choice. Editors set how many options a voter can pick, the legend shown above the options, and whether the options appear in a random order.
- Anonymous or members only. An open poll accepts votes from anonymous visitors when it allows them, and when visitors can see its parent folder: publish the folder before opening the poll. A cookie keeps an anonymous visitor from voting twice.
- Results the editors choose. Voters can see partial results after voting, and the results show as bars, a pie, or plain numbers. In a multiple choice poll, each percentage is the share of voters who picked the option, and a pie shows as bars.
- A Volto block. The Poll block shows the latest open poll of the site section, the latest closed one when none is open, or a poll the editor picks. It also works inside a Grid.
- A REST API.
GET @pollanswers the state of a poll for the current user, andPOST @voterecords a vote. - Export and import. With
plone.exportimport, a closed poll's votes go out with its content and come back on import. The REST API never reads or writes them. - An upgrade from 2.x. The upgrade step moves the stored votes to the new storage, and removes the voting portlets, which the Poll block replaces.
Polls have their own workflow, with the states Private, Pending review, Open, and Closed.
- A new poll is Private. Its owner, editors, managers, and site administrators can change it.
- From Private, a poll goes to Pending review, or straight to Open for someone who can review content.
- While Pending review, managers, reviewers, and site administrators can change it. A reviewer opens it, or sends it back to Private.
- An Open poll collects votes, and nobody can change it.
- Reviewers, managers, and site administrators close an Open poll, or send it back to Private. Sending it back removes all of its votes.
- A Closed poll shows its final results. Nobody can change it or vote in it, and it can be opened again.
The documentation lives at collective.github.io/collective.polls, and its sources in docs/.
To build it locally, run the following commands.
make docs-install
make docs-buildThe add-on comes in two packages, and a site needs both.
Add collective.polls to your project's dependencies, then install it in your Plone site from the Add-ons control panel.
uv add collective.pollsAdd @plone-collective/volto-polls to your Volto project.
pnpm add @plone-collective/volto-pollsThen list it in the addons of your volto.config.js.
const addons = ['@plone-collective/volto-polls'];- An operating system that runs all the requirements mentioned.
- uv
- nvm
- Node.js and pnpm 24
- Make
- Git
- Docker (optional)
-
Clone this repository, then change your working directory.
git clone git@github.com:collective/collective.polls.git cd collective.polls -
Install this code base.
make install
-
Create a new Plone site on your first run. It comes with example content, including polls.
make backend-create-site
-
Start the backend at http://localhost:8080/.
make backend-start
-
In a new shell session, start the frontend at http://localhost:3000/.
make frontend-start
Deploy a local Docker Compose environment that includes the following.
- Docker images for the backend and the frontend 🖼️
- A stack with a Traefik router and a PostgreSQL database 🗃️
- Accessible at http://collective.polls.localhost 🌐
Run the following commands in a shell session.
make stack-create-site
make stack-startThis monorepo consists of the following sections.
- backend: The
collective.pollsPlone add-on, installed with uv instead of buildout. - frontend: The
@plone-collective/volto-pollsVolto add-on. - docs: The documentation, built with Sphinx and the Plone Sphinx Theme.
- Everything needed to run a site with the add-on is in the repository.
- Each section has its own GitHub workflows, which run only when it changes (see
.github/workflows). - It makes building a Docker image for each section simple.
To check your code against quality standards, run the following shell command.
make checkTo format and rewrite the code base, ensuring it adheres to quality standards, run the following shell command.
make format| Section | Tool | Description | Configuration |
|---|---|---|---|
| backend | Ruff | Python code formatting, imports sorting | backend/pyproject.toml |
| backend | zpretty |
XML and ZCML formatting | -- |
| frontend | ESLint | Fixes most common frontend issues | frontend/.eslintrc.js |
| frontend | prettier | Format JS and Typescript code | frontend/.prettierrc |
| frontend | Stylelint | Format Styles (css, less, sass) | frontend/.stylelintrc |
Formatters can also be run within the backend or frontend folders.
To check the code base without changing it, run the following shell command.
make lint| Section | Tool | Description | Configuration |
|---|---|---|---|
| backend | Ruff | Checks code formatting, imports sorting | backend/pyproject.toml |
| backend | Pyroma | Checks Python package metadata | -- |
| backend | check-python-versions | Checks Python version information | -- |
| backend | zpretty |
Checks XML and ZCML formatting | -- |
| frontend | ESLint | Checks JS / Typescript lint | frontend/.eslintrc.js |
| frontend | prettier | Check JS / Typescript formatting | frontend/.prettierrc |
| frontend | Stylelint | Check Styles (css, less, sass) formatting | frontend/.stylelintrc |
Linters can be run individually within the backend or frontend folders.
Generate the translation files for Plone and Volto with the following command.
make i18n| Package | Description |
|---|---|
collective.polls |
The Plone backend add-on. |
@plone-collective/volto-polls |
The Volto frontend add-on. |
Got an idea? Found a bug? Let us know by opening an issue.
Generated using Cookieplone (2.0.0) and cookieplone-templates (99c2201) on 2026-10-04 22:40:50.366931. A special thanks to all contributors and supporters!