In a previous post, I have described how to set up your own Staticman instance and use it to run a commenting system. Since Staticman is not limited to bringing comments to static sites, I decided to implement polls with Staticman as well.
In order to get polls working, the following steps need to be followed:
- Adjust your Staticman configuration to include a configuration for polls
- Create two subfolders in your data folder: one for storing the votes and one for setting up the polls
- Implement the Hugo template logic for the polls in your partials
Configuring Staticman for polls is relatively straight-forward. The most important parameters in the
staticman.yml config file are the following:
path, set the data folder for storing the poll votes.
requiredFieldsset the fields that should be associated with every vote:
- path: the location on your website where the poll was accessed.
- pollID: a unique identifier of the poll. This is used to associate votes with polls.
- option: the selected poll option (i.e. the vote). This is stored to increment the vote count when generating the site.
- ipAddress: the IP address of the voter. The IP address is stored to prevent the same user from voting multiple times.
transforms, the IP address should be anonymized using md5.
moderationfield can be set to
falsesince moderation is not necessary for polls.
For further details, please take a look at my Staticman configuration.
For polls, we want to set up two folders in the website’s data folder:
- A folder containing the votes. We will call this folder
pollsin the following.
- A folder for setting up the polls on your page. We will call this folder
pollSetupin the following.
polls folder is the folder where Hugo stores the individual votes, so we do not need to do anything except to create the folder.
pollSetup folder, however, needs to contain the definitions of the polls that we would like to show on the page. So, how should a poll configuration look like? I am using
toml files with the following variables:
An example configuration could look like the following file.
Note that if multiple polls have the attribute
show_poll set to
true, an arbitrary poll from these will be shown in the sidebar. So, typically, you should make sure that at most one poll has this flag set to
Hugo template logic
To implement the logic for polls, I have created a new partial template. The following paragraphs describe the most important steps for collecting votes and visualizing them.
Retrieving the appropriate setup file
The first step is to select the setup file that should be used for building the poll. We store the information about the poll. If an external poll ID was not specified, we select one of the polls that has
show_poll set to
true. Otherwise, we select the poll that corresponds to the provided poll ID:
Counting the number of votes
To count the number of votes, we iterate over all poll votes. We only consider those votes where the poll’s ID matches the poll ID specified by the active poll. For these votes, we store the IP in a string and increment the number of votes for the selected option.
Poll submission system
For the poll submission system, we need to set up a post form. Via the hidden fields inputs, the form specifies the parameters that are used for the polls, as defined in your Staticman configuration. There are two additional entries that I use:
- pollActive: This field (string representing a boolean) indicates whether the poll is currently active.
Finally, the submit button is used to trigger the forms action, which is set to the Staticman API call for the polls context.
Viewing the results
For viewing the poll results, the main tasks are the following:
- Count the total number of votes.
- Find the percentage of votes for each option by dividing by the total number of votes. Here, it is important to typecast to floats and round appropriately.
- Show the results by indicating three things.
- The poll option
- A bar indicating the percentage of votes
- The percentage itself
- Display the total number of votes below the individual results.
- Decide whether a vote is possible.
- Decide whether the poll options or the results should be shown.
Inclusion of the poll partial
So, now that we have all the components together, we can just include the partial template for the polls in some part of the page. Enjoy the polls!