@@ -4,3 +4,4 @@ | |||||
.bundle/config | .bundle/config | ||||
/.ruby-gemset | /.ruby-gemset | ||||
/tmp/ | /tmp/ | ||||
_* |
@@ -0,0 +1,292 @@ | |||||
#!/usr/bin/env ruby | |||||
# Generate a static site | |||||
require 'logger' | |||||
require 'haml' | |||||
require_relative '../models' | |||||
OUTPUT_DIR = '_site' | |||||
VIEWS_DIR = File.join('..', 'views') | |||||
LAYOUT_FN = File.join(VIEWS_DIR, 'layout.haml') | |||||
@log = Logger.new($stdout) | |||||
@log.level = Logger::INFO | |||||
@log.info "Build starts." | |||||
@log.info "Output directory is: #{OUTPUT_DIR}" | |||||
class String | |||||
def pluralize(num) | |||||
if num == 1 | |||||
return self | |||||
end | |||||
case self[-1] | |||||
when 'y' | |||||
self[0..-2] + 'ies' | |||||
when 's' | |||||
self + "es" | |||||
else | |||||
self + "s" | |||||
end | |||||
end | |||||
end | |||||
def commify(num) | |||||
num.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse | |||||
end | |||||
# From http://snippets.dzone.com/posts/show/593 | |||||
def to_ordinal(num) | |||||
num = num.to_i | |||||
if (10...20) === num | |||||
"#{num}th" | |||||
else | |||||
g = %w{ th st nd rd th th th th th th } | |||||
a = num.to_s | |||||
c = a[-1..-1].to_i | |||||
a + g[c] | |||||
end | |||||
end | |||||
def format_percent(num) | |||||
sprintf("%.0f%%", num) | |||||
end | |||||
def short_date(d) | |||||
d.strftime("%e %b %Y") | |||||
end | |||||
def long_date(d) | |||||
d.strftime("%e %B %Y") | |||||
end | |||||
# Exception for Labour/Co-operative candidacies | |||||
def party_name(labcoop, party_name) | |||||
labcoop ? "Labour and Co-operative Party" : party_name | |||||
end | |||||
def write_page(path_items, template, locals = {}) | |||||
dir = File.join(path_items) | |||||
FileUtils.mkdir_p(dir) | |||||
@log.debug dir | |||||
fn = File.join(dir, 'index.html') | |||||
# https://stackoverflow.com/questions/6125265/using-layouts-in-haml-files-independently-of-rails | |||||
html = Haml::Engine.new(File.read(LAYOUT_FN)).render do | |||||
Haml::Engine.new(File.read(File.join(VIEWS_DIR, "#{template}.haml"))).render(Object.new, locals) | |||||
end | |||||
File.write(fn, html) | |||||
@log.info fn | |||||
# TODO - add page to sitemap.xml or sitemap.txt | |||||
# https://support.google.com/webmasters/answer/183668?hl=en&ref_topic=4581190 | |||||
end | |||||
test_dir = File.join(Dir.pwd, OUTPUT_DIR) | |||||
# FIXME - clear output directory at the start of every run | |||||
# FileUtils.rm_rf(test_dir) | |||||
Dir.mkdir(test_dir) unless File.directory?(test_dir) | |||||
Dir.chdir(test_dir) | |||||
# Copy `public` dir to output dir | |||||
FileUtils.copy_entry(File.join('..', 'public'), '.') | |||||
# Home page | |||||
locals = { | |||||
future_elections: Election.future, | |||||
past_elections: Election.past | |||||
} | |||||
write_page('.', 'index', locals) | |||||
# Election pages | |||||
Election.each do |e| | |||||
locals = { | |||||
body: Body.first(:slug => e.body.slug), | |||||
election: Election.first(:body => e.body, :d => e.d), | |||||
elections_for_this_body: Election.all(:body => e.body, :order => [:d]), | |||||
total_seats: Candidacy.sum(:seats, :election => e), | |||||
total_votes: Candidacy.sum(:votes, :election => e) | |||||
} | |||||
# There's got to be a better way to do this, either with SQL or Datamapper | |||||
locals['total_districts'] = repository(:default).adapter.select(" | |||||
SELECT district_id | |||||
FROM candidacies | |||||
WHERE election_id = ? | |||||
GROUP BY district_id | |||||
ORDER BY district_id | |||||
", e.id).count | |||||
locals['results_by_party'] = repository(:default).adapter.select(" | |||||
SELECT | |||||
p.colour, | |||||
p.name, | |||||
SUM(c.votes) AS votez, | |||||
SUM(c.seats) AS seatz, | |||||
COUNT(*) AS cands | |||||
FROM candidacies c | |||||
LEFT JOIN parties p ON p.id = c.party_id | |||||
WHERE c.election_id = ? | |||||
GROUP BY c.party_id, p.colour, p.name | |||||
ORDER BY seatz DESC, votez DESC | |||||
", e.id) | |||||
write_page(['bodies', e.body.slug, 'elections', e.d.to_s], 'electionsummary', locals) | |||||
# District results for this election (resultsdistrict) | |||||
# Loop through all districts in this election | |||||
e.candidacies.districts.each do |d| | |||||
total_seats = Candidacy.sum(:seats, :district => d, :election => e) | |||||
total_votes = Candidacy.sum(:votes, :district => d, :election => e) | |||||
poll = Poll.get(d.id, e.id) | |||||
locals = { | |||||
district: d, | |||||
body: d.body, | |||||
election: e, | |||||
candidacies: Candidacy.all(:district => d, :election => e, :order => [:position]), | |||||
total_votes: total_votes, | |||||
total_candidates: Candidacy.count(:district => d, :election => e), | |||||
total_seats: total_seats, | |||||
districts_in_this_election: e.candidacies.districts, | |||||
poll: poll | |||||
} | |||||
locals['share_message'] = nil | |||||
if total_seats == 1 | |||||
locals['share_denominator'] = total_votes | |||||
elsif poll && poll.valid_ballot_papers | |||||
locals['share_denominator'] = poll.valid_ballot_papers | |||||
else | |||||
locals['share_denominator'] = total_votes / total_seats | |||||
locals['share_message'] = "The vote share percentages have been estimated as we don't have data for the number of valid ballot papers in this poll." | |||||
end | |||||
# Postgres: All the columns selected when using GROUP BY must either be aggregate functions or appear in the GROUP BY clause | |||||
locals['results_by_party'] = repository(:default).adapter.select(" | |||||
SELECT | |||||
p.name AS party_name, | |||||
p.colour AS party_colour, | |||||
COUNT(c.id) AS num_candidates, | |||||
SUM(c.seats) AS num_seats, | |||||
SUM(c.votes) AS total_votes | |||||
FROM candidacies c | |||||
LEFT JOIN parties p | |||||
ON c.party_id = p.id | |||||
WHERE c.district_id = ? | |||||
AND c.election_id = ? | |||||
GROUP BY p.name, p.colour | |||||
ORDER BY total_votes DESC | |||||
", d.id, e.id) | |||||
write_page(['bodies', e.body.slug, 'elections', e.d.to_s, e.body.districts_name, d.slug], 'resultsdistrict', locals) | |||||
end | |||||
end | |||||
# Candidate index | |||||
locals = { candidates: Candidate.all(:order => [ :surname, :forenames ]) } | |||||
write_page('candidates', 'candidates', locals) | |||||
# Candidate pages | |||||
# FIXME: What do we do about deleted candidates/redirects? | |||||
Candidate.each do |c| | |||||
locals = { | |||||
candidate: c | |||||
} | |||||
locals['candidacies'] = repository(:default).adapter.select(" | |||||
SELECT | |||||
e.d, | |||||
c.*, | |||||
p.name AS party_name, | |||||
p.colour AS party_colour, | |||||
b.name AS body_name, | |||||
b.slug AS body_slug, | |||||
b.districts_name AS districts_name, | |||||
d.name AS district_name, | |||||
d.slug AS district_slug | |||||
FROM candidacies c | |||||
INNER JOIN elections e | |||||
ON c.election_id = e.id | |||||
INNER JOIN parties p | |||||
ON c.party_id = p.id | |||||
INNER JOIN bodies b | |||||
ON e.body_id = b.id | |||||
INNER JOIN districts d | |||||
ON c.district_id = d.id | |||||
WHERE c.candidate_id = ? | |||||
ORDER BY d | |||||
", c.id) | |||||
write_page(['candidates', c.id.to_s], 'candidate', locals) | |||||
end | |||||
# Bodies index | |||||
dir = 'bodies' | |||||
FileUtils.mkdir_p(dir) | |||||
@log.debug dir | |||||
fn = File.join(dir, 'index.html') | |||||
FileUtils.touch(fn) # empty file | |||||
@log.info fn | |||||
# Body detail pages | |||||
Body.each do |b| | |||||
locals = { | |||||
body: b, | |||||
districts: District.all(:body => b, :order => [:name]) | |||||
} | |||||
locals['elections'] = repository(:default).adapter.select(" | |||||
SELECT | |||||
e.id, | |||||
e.kind, | |||||
e.d, | |||||
SUM(p.ballot_papers_issued)::float / SUM(p.electorate) * 100 AS turnout_percent | |||||
FROM elections e | |||||
LEFT JOIN polls p | |||||
ON e.id = p.election_id | |||||
WHERE e.body_id = ? | |||||
GROUP BY p.election_id, e.id | |||||
ORDER BY e.d DESC | |||||
", b.id) | |||||
write_page(['bodies', b.slug], 'body', locals) | |||||
# Districts for this body | |||||
b.districts.each do |d| | |||||
locals = { | |||||
district: d, | |||||
body: b | |||||
} | |||||
write_page(['bodies', b.slug, b.districts_name, d.slug], 'district', locals) | |||||
end | |||||
end | |||||
write_page('about', 'about') | |||||
write_page('guides', 'guides') | |||||
write_page(%w(guides how-the-parliament-election-works), 'parliament') | |||||
write_page(%w(guides how-the-council-election-works), 'election') | |||||
@log.info "Build complete." |
@@ -1,4 +1,4 @@ | |||||
%h1= @page_title = @body.name | |||||
%h1= page_title = body.name | |||||
%h2 Elections | %h2 Elections | ||||
@@ -8,10 +8,10 @@ | |||||
%th | %th | ||||
%th | %th | ||||
%th turnout | %th turnout | ||||
- @elections.each do |election| | |||||
- elections.each do |election| | |||||
%tr | %tr | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{@body.slug}/elections/#{election.d}" }< | |||||
%a{ :href => "/bodies/#{body.slug}/elections/#{election.d}" }< | |||||
= short_date(election.d) | = short_date(election.d) | ||||
%td | %td | ||||
= election.kind | = election.kind | ||||
@@ -20,9 +20,9 @@ | |||||
= format_percent(election.turnout_percent) | = format_percent(election.turnout_percent) | ||||
%h2 | %h2 | ||||
= @body.districts_name.capitalize | |||||
= body.districts_name.capitalize | |||||
- @districts.each do |district| | |||||
- districts.each do |district| | |||||
%p | %p | ||||
%a{ :href => "/bodies/#{@body.slug}/#{@body.districts_name}/#{district.slug}" } | |||||
%a{ :href => "/bodies/#{body.slug}/#{body.districts_name}/#{district.slug}" } | |||||
= district.name | = district.name |
@@ -2,7 +2,7 @@ | |||||
%a{ :href => "/candidates" } | %a{ :href => "/candidates" } | ||||
« All candidates | « All candidates | ||||
%h1= @page_title = @candidate.name | |||||
%h1= page_title = candidate.name | |||||
%h2 Elections contested | %h2 Elections contested | ||||
@@ -17,7 +17,7 @@ | |||||
%th position | %th position | ||||
%th | %th | ||||
- @candidacies.each do |ccy| | |||||
- candidacies.each do |ccy| | |||||
%tr | %tr | ||||
%td{ :style => "background-color: #{ccy['party_colour']}" } | %td{ :style => "background-color: #{ccy['party_colour']}" } | ||||
%td | %td | ||||
@@ -46,6 +46,6 @@ | |||||
%p | %p | ||||
Some candidates have more than one profile page due to them using slightly different names in different elections. See the full | Some candidates have more than one profile page due to them using slightly different names in different elections. See the full | ||||
%a{ :href => "/candidates/##{@candidate.surname[0]}" }< | |||||
%a{ :href => "/candidates/##{candidate.surname[0]}" }< | |||||
candidates list | candidates list | ||||
for details. | for details. |
@@ -1,21 +1,21 @@ | |||||
%h1= @page_title = "Candidates" | |||||
%h1= page_title = "Candidates" | |||||
%nav.letter_index | %nav.letter_index | ||||
- ("A".."Z").each do |letter| | - ("A".."Z").each do |letter| | ||||
%a{ :href => "##{letter}" }< | %a{ :href => "##{letter}" }< | ||||
= letter | = letter | ||||
- @first_letter = '' | |||||
- first_letter = '' | |||||
%table | %table | ||||
- @candidates.each do |c| | |||||
- if c.surname[0] != @first_letter | |||||
- @first_letter = c.surname[0] | |||||
- candidates.each do |c| | |||||
- if c.surname[0] != first_letter | |||||
- first_letter = c.surname[0] | |||||
%tr.noborder | %tr.noborder | ||||
%td | %td | ||||
%td | %td | ||||
%tr.noborder{ :name => @first_letter, :id => @first_letter } | |||||
%td.strong{ :style => "font-size: 300%;" }= @first_letter.upcase | |||||
%tr.noborder{ :name => first_letter, :id => first_letter } | |||||
%td.strong{ :style => "font-size: 300%;" }= first_letter.upcase | |||||
%td | %td | ||||
%tr | %tr | ||||
%td | %td | ||||
@@ -1,26 +1,26 @@ | |||||
- @page_title = "#{@district.name} #{@district.body.district_name}, #{@district.body.name}" | |||||
- page_title = "#{district.name} #{district.body.district_name}, #{district.body.name}" | |||||
%nav | %nav | ||||
%a{ :href => "/bodies/#{@district.body.slug}" } | |||||
%a{ :href => "/bodies/#{district.body.slug}" } | |||||
« | « | ||||
= @district.body.name | |||||
= district.body.name | |||||
%h1= "#{@district.name} #{@district.body.district_name}" | |||||
%h1= "#{district.name} #{district.body.district_name}" | |||||
-# | -# | ||||
- @election = Election.get(9) # FIXME magic number | |||||
- election = Election.get(9) # FIXME magic number | |||||
%h2 | %h2 | ||||
= @district.name | |||||
= district.name | |||||
ward candidates for the | ward candidates for the | ||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}"} | |||||
= @election.body.name | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}"} | |||||
= election.body.name | |||||
election on | election on | ||||
= long_date(@election.d) | |||||
= long_date(election.d) | |||||
%table | %table | ||||
- Candidacy.all(:election => @election, :district => @district, :order => [:party_id]).each do |c| | |||||
- campaign = Campaign.first(:party => c.party, :election => @election) | |||||
- Candidacy.all(:election => election, :district => district, :order => [:party_id]).each do |c| | |||||
- campaign = Campaign.first(:party => c.party, :election => election) | |||||
%tr.vcard | %tr.vcard | ||||
%td{ :style => "background-color: #{c.party.colour}" } | %td{ :style => "background-color: #{c.party.colour}" } | ||||
%td.candidate_name.fn | %td.candidate_name.fn | ||||
@@ -42,12 +42,12 @@ | |||||
%h2 Candidates elected | %h2 Candidates elected | ||||
- Election.all(:body => @district.body, :order => [:d.desc]).each do |election| | |||||
- ccys = Candidacy.all(:election_id => election.id, :district_id => @district.id, :seats => 1, :order => [:votes.desc]) | |||||
- Election.all(:body => district.body, :order => [:d.desc]).each do |election| | |||||
- ccys = Candidacy.all(:election_id => election.id, :district_id => district.id, :seats => 1, :order => [:votes.desc]) | |||||
- unless ccys == [] | - unless ccys == [] | ||||
%h3 | %h3 | ||||
%a{ :href => "/bodies/#{@district.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{@district.slug}"} | |||||
%a{ :href => "/bodies/#{district.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{district.slug}"} | |||||
= long_date election.d | = long_date election.d | ||||
= election.kind | = election.kind | ||||
@@ -19,5 +19,3 @@ | |||||
%p If a political party gets 28 or more councillors they get to run Sutton Council and decide its policies and services. | %p If a political party gets 28 or more councillors they get to run Sutton Council and decide its policies and services. | ||||
%p If no party gets 28 councillors the parties have to agree among themselves who will run the council. This is called “no overall control”. | %p If no party gets 28 councillors the parties have to agree among themselves who will run the council. This is called “no overall control”. | ||||
= haml :register, :layout => false |
@@ -1,66 +1,66 @@ | |||||
- @page_title = "#{@election.body.name} #{@election.kind} #{long_date(@election.d)}" | |||||
- page_title = "#{election.body.name} #{election.kind} #{long_date(election.d)}" | |||||
%nav | %nav | ||||
%a{ :href => "/bodies/#{@election.body.slug}" } | |||||
%a{ :href => "/bodies/#{election.body.slug}" } | |||||
« | « | ||||
= @election.body.name | |||||
= election.body.name | |||||
- if @elections_for_this_body.size > 1 | |||||
- if elections_for_this_body.size > 1 | |||||
%p | %p | ||||
- @election_index = @elections_for_this_body.index(@election) | |||||
- election_index = elections_for_this_body.index(election) | |||||
- unless @election_index == 0 | |||||
- @previous_election = @elections_for_this_body[@election_index - 1] | |||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@previous_election.d}", :title => "#{@previous_election.kind} #{short_date(@previous_election.d)}" } | |||||
- unless election_index == 0 | |||||
- previous_election = elections_for_this_body[election_index - 1] | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{previous_election.d}", :title => "#{previous_election.kind} #{short_date(previous_election.d)}" } | |||||
« | « | ||||
Previous | Previous | ||||
= @election.body.name | |||||
= election.body.name | |||||
election | election | ||||
| | ||||
- unless @election_index == @elections_for_this_body.size - 1 | |||||
- @next_election = @elections_for_this_body[@election_index + 1] | |||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@next_election.d}", :title => "#{@next_election.kind} #{short_date(@next_election.d)}" } | |||||
- unless election_index == elections_for_this_body.size - 1 | |||||
- next_election = elections_for_this_body[election_index + 1] | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{next_election.d}", :title => "#{next_election.kind} #{short_date(next_election.d)}" } | |||||
Next | Next | ||||
= @election.body.name | |||||
= election.body.name | |||||
election | election | ||||
» | » | ||||
%h1 | %h1 | ||||
= @election.body.name | |||||
= @election.kind | |||||
= election.body.name | |||||
= election.kind | |||||
%br | %br | ||||
= long_date(@election.d) | |||||
= long_date(election.d) | |||||
-# Does this election have any recorded votes, i.e. has it been held? | -# Does this election have any recorded votes, i.e. has it been held? | ||||
- @election_held = Candidacy.sum(:votes, :election => @election) | |||||
- election_held = Candidacy.sum(:votes, :election => election) | |||||
- unless @election_held | |||||
- unless election_held | |||||
.warning | .warning | ||||
We don't have the results for this election yet. | We don't have the results for this election yet. | ||||
%p= @polling_station | |||||
-# %p= polling_station | |||||
%p= @election.reason | |||||
%p= election.reason | |||||
%p | %p | ||||
= @election.candidacies.count | |||||
= "candidate".pluralize(@election.candidacies.count) | |||||
- if @election_held | |||||
= election.candidacies.count | |||||
= "candidate".pluralize(election.candidacies.count) | |||||
- if election_held | |||||
contested | contested | ||||
- else | - else | ||||
will be contesting | will be contesting | ||||
-# We can't calculate the number of seats being contested if the election hasn't been held | -# We can't calculate the number of seats being contested if the election hasn't been held | ||||
- if @election_held | |||||
= @total_seats | |||||
= "seat".pluralize(@total_seats) | |||||
- if election_held | |||||
= total_seats | |||||
= "seat".pluralize(total_seats) | |||||
in | in | ||||
= @total_districts | |||||
= @election.body.district_name.pluralize(@total_districts) | |||||
= total_districts | |||||
= election.body.district_name.pluralize(total_districts) | |||||
in Sutton. | in Sutton. | ||||
- if @election_held | |||||
- if election_held | |||||
%table | %table | ||||
%tr.header | %tr.header | ||||
@@ -69,69 +69,69 @@ | |||||
%th.highlight seats won | %th.highlight seats won | ||||
%th votes | %th votes | ||||
%th % votes | %th % votes | ||||
- if @total_seats > 1 | |||||
- if total_seats > 1 | |||||
%th % seats | %th % seats | ||||
%th votes per seat | %th votes per seat | ||||
%th candidates | %th candidates | ||||
%th votes per candidate | %th votes per candidate | ||||
-# | -# | ||||
%th relative popularity | %th relative popularity | ||||
- @max_votes_per_candidate = @results_by_party.first.votez.to_f / @results_by_party.first.cands.to_f # We really need to scan the array for the max value | |||||
- @results_by_party.each do |row| | |||||
- max_votes_per_candidate = results_by_party.first.votez.to_f / results_by_party.first.cands.to_f # We really need to scan the array for the max value | |||||
- results_by_party.each do |row| | |||||
%tr | %tr | ||||
%td{ :style => "background-color: #{row.colour}" } | %td{ :style => "background-color: #{row.colour}" } | ||||
%td.data_party= row.name | %td.data_party= row.name | ||||
%td.data_seats.right.highlight= row.seatz | %td.data_seats.right.highlight= row.seatz | ||||
%td.data_votes.right= commify(row.votez) | %td.data_votes.right= commify(row.votez) | ||||
- if @election_held | |||||
%td.right= format_percent(row.votez.to_f / @total_votes * 100) | |||||
- if @total_seats > 1 | |||||
%td.right= format_percent(row.seatz.to_f / @total_seats * 100) | |||||
- if election_held | |||||
%td.right= format_percent(row.votez.to_f / total_votes * 100) | |||||
- if total_seats > 1 | |||||
%td.right= format_percent(row.seatz.to_f / total_seats * 100) | |||||
%td.data_votes_per_seat.right | %td.data_votes_per_seat.right | ||||
- if row.seatz > 0 | - if row.seatz > 0 | ||||
= commify(row.votez / row.seatz) | = commify(row.votez / row.seatz) | ||||
- else | - else | ||||
— | — | ||||
%td.data_candidates.right= row.cands | %td.data_candidates.right= row.cands | ||||
- if @election_held && @total_seats > 1 | |||||
- if election_held && total_seats > 1 | |||||
%td.right= commify(row.votez / row.cands) | %td.right= commify(row.votez / row.cands) | ||||
-# | -# | ||||
%td.right= format_percent( ( row.votez.to_f / row.cands.to_f ) / @max_votes_per_candidate * 100) | |||||
%td.right= format_percent( ( row.votez.to_f / row.cands.to_f ) / max_votes_per_candidate * 100) | |||||
%tr.footer | %tr.footer | ||||
%td | %td | ||||
%td | %td | ||||
%td.right.highlight= @total_seats | |||||
%td.right= commify(@total_votes) | |||||
%td.right.highlight= total_seats | |||||
%td.right= commify(total_votes) | |||||
%td | %td | ||||
- if @total_seats > 1 | |||||
- if total_seats > 1 | |||||
%td | %td | ||||
%td | %td | ||||
%td.right= commify(@election.candidacies.count) | |||||
%td.right= commify(election.candidacies.count) | |||||
%td | %td | ||||
- if @election.ballot_papers_issued | |||||
- if election.ballot_papers_issued | |||||
%table | %table | ||||
%tr | %tr | ||||
%td Electorate | %td Electorate | ||||
%td.right= commify(@election.electorate) | |||||
%td.right= commify(election.electorate) | |||||
%tr | %tr | ||||
%td Ballot papers issued | %td Ballot papers issued | ||||
%td.right= commify(@election.ballot_papers_issued) | |||||
%td.right= commify(election.ballot_papers_issued) | |||||
%tr | %tr | ||||
%td Turnout | %td Turnout | ||||
%td.right= sprintf("%.0f%%", @election.ballot_papers_issued / @election.electorate.to_f * 100) | |||||
%td.right= sprintf("%.0f%%", election.ballot_papers_issued / election.electorate.to_f * 100) | |||||
%h2 | %h2 | ||||
= "Candidate".pluralize(@total_seats) | |||||
= "Candidate".pluralize(total_seats) | |||||
elected | elected | ||||
%table | %table | ||||
- @election.polls.each do |p| | |||||
- election.polls.each do |p| | |||||
%tr | %tr | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{p.district.slug}"} | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{p.district.slug}"} | |||||
= p.district.name | = p.district.name | ||||
- p.successful_candidacies.each do |sc| | - p.successful_candidacies.each do |sc| | ||||
%td{ :style => "background-color: #{sc.party.colour};" } | %td{ :style => "background-color: #{sc.party.colour};" } | ||||
@@ -1,16 +1,17 @@ | |||||
#lookup | |||||
%h2= @election_title | |||||
%form{ :method => 'get', :action => '/' } | |||||
%label{ :for => "postcode" } My postcode is | |||||
%input{ :type => 'text', :name => 'postcode', :value => @default_pc, :size => 8, :maxlength => 8 } | |||||
%input{ :type => 'submit', :value => "Find my results" } | |||||
-# | |||||
#lookup | |||||
%h2= @election_title | |||||
%form{ :method => 'get', :action => '/' } | |||||
%label{ :for => "postcode" } My postcode is | |||||
%input{ :type => 'text', :name => 'postcode', :value => @default_pc, :size => 8, :maxlength => 8 } | |||||
%input{ :type => 'submit', :value => "Find my results" } | |||||
- if @future_elections.size > 0 | |||||
- if future_elections.size > 0 | |||||
%h2 Upcoming elections | %h2 Upcoming elections | ||||
%table | %table | ||||
- @future_elections.each do |election| | |||||
- future_elections.each do |election| | |||||
%tr | %tr | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | ||||
@@ -20,12 +21,12 @@ | |||||
%td | %td | ||||
= election.kind | = election.kind | ||||
- if @past_elections.size > 0 | |||||
- if past_elections.size > 0 | |||||
%h2 Past elections | %h2 Past elections | ||||
%table | %table | ||||
- @past_elections.each do |election| | |||||
- past_elections.each do |election| | |||||
%tr | %tr | ||||
%td | %td | ||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | ||||
@@ -2,7 +2,7 @@ | |||||
%html | %html | ||||
%head | %head | ||||
%title= @page_title ? @page_title + " - Sutton Elections" : "Sutton Elections - Your guide to voting and election results in the London Borough of Sutton" | %title= @page_title ? @page_title + " - Sutton Elections" : "Sutton Elections - Your guide to voting and election results in the London Borough of Sutton" | ||||
%link{ :rel => 'stylesheet', :type => 'text/css', :href => 'http://yui.yahooapis.com/pure/0.6.0/pure-min.css' } | |||||
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"> | |||||
%link{ :rel => 'stylesheet', :type => 'text/css', :href => '/style.css' } | %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/style.css' } | ||||
%link{ :rel => 'stylesheet', :type => 'text/css', :href => '/print.css', :media => 'print' } | %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/print.css', :media => 'print' } | ||||
%meta{ :name => 'referrer', :content => 'no-referrer' } | %meta{ :name => 'referrer', :content => 'no-referrer' } | ||||
@@ -28,10 +28,11 @@ | |||||
%a{ :href => '/about' } About | %a{ :href => '/about' } About | ||||
#main | #main | ||||
- if flash[:notice] | |||||
#notice | |||||
%p= flash[:notice] | |||||
- if flash[:error] | |||||
#error | |||||
%p= flash[:error] | |||||
-# - if flash[:notice] | |||||
-# #notice | |||||
-# %p= flash[:notice] | |||||
-# - if flash[:error] | |||||
-# #error | |||||
-# %p= flash[:error] | |||||
= yield | = yield |
@@ -23,5 +23,3 @@ | |||||
%p If no party gets 326 MPs the parties have to agree among themselves who will run the country. This is called a “hung parliament”. | %p If no party gets 326 MPs the parties have to agree among themselves who will run the country. This is called a “hung parliament”. | ||||
%p Elections for parliament must be held at least once every five years. The prime minister can choose to have an election earlier if they wish. | %p Elections for parliament must be held at least once every five years. The prime minister can choose to have an election earlier if they wish. | ||||
= haml :register, :layout => false |
@@ -1,35 +1,35 @@ | |||||
- @page_title = "#{@district.name} #{@district.body.district_name} results, #{@body.name} election #{short_date(@election.d)}" | |||||
- page_title = "#{district.name} #{district.body.district_name} results, #{body.name} election #{short_date(election.d)}" | |||||
%nav | %nav | ||||
- if @districts_in_this_election.size > 1 | |||||
- @district_index = @districts_in_this_election.index(@district) | |||||
- if districts_in_this_election.size > 1 | |||||
- district_index = districts_in_this_election.index(district) | |||||
- unless @district_index == 0 # Don't show the previous link if this is the first district for this election | |||||
- @previous_district = @districts_in_this_election[@district_index - 1] | |||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{@previous_district.slug}" } | |||||
- unless district_index == 0 # Don't show the previous link if this is the first district for this election | |||||
- previous_district = districts_in_this_election[district_index - 1] | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{previous_district.slug}" } | |||||
« | « | ||||
= @previous_district.name | |||||
= previous_district.name | |||||
| | ||||
- unless @district_index == @districts_in_this_election.size - 1 # Don't show the next link if this is the last district for this election | |||||
- @next_district = @districts_in_this_election[@district_index + 1] | |||||
%a{ :href => "/bodies/#{@election.body.slug}/elections/#{@election.d}/#{@election.body.districts_name}/#{@next_district.slug}" } | |||||
= @next_district.name | |||||
- unless district_index == districts_in_this_election.size - 1 # Don't show the next link if this is the last district for this election | |||||
- next_district = districts_in_this_election[district_index + 1] | |||||
%a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}/#{election.body.districts_name}/#{next_district.slug}" } | |||||
= next_district.name | |||||
» | » | ||||
%p | %p | ||||
%a{ :href => "/bodies/#{@district.body.slug}/elections/#{@election.d}" } | |||||
= @body.name | |||||
= @election.kind | |||||
= long_date(@election.d) | |||||
%a{ :href => "/bodies/#{district.body.slug}/elections/#{election.d}" } | |||||
= body.name | |||||
= election.kind | |||||
= long_date(election.d) | |||||
%h1 | %h1 | ||||
%a{ :href => "/bodies/#{@district.body.slug}/#{@district.body.district_name.pluralize(2)}/#{@district.slug}" } | |||||
= @district.name + " " + @district.body.district_name | |||||
%a{ :href => "/bodies/#{district.body.slug}/#{district.body.district_name.pluralize(2)}/#{district.slug}" } | |||||
= district.name + " " + district.body.district_name | |||||
- @election_held = Candidacy.sum(:votes, :election => @election, :district => @district) | |||||
- election_held = Candidacy.sum(:votes, :election => election, :district => district) | |||||
- unless @election_held | |||||
- unless election_held | |||||
.warning | .warning | ||||
We don't have the results for this election yet. | We don't have the results for this election yet. | ||||
@@ -44,7 +44,7 @@ | |||||
%th | %th | ||||
- count = 0 | - count = 0 | ||||
- @candidacies.each do |candidacy| | |||||
- candidacies.each do |candidacy| | |||||
- count += 1 | - count += 1 | ||||
%tr.vcard | %tr.vcard | ||||
%td= count | %td= count | ||||
@@ -54,9 +54,9 @@ | |||||
= candidacy.candidate.short_name | = candidacy.candidate.short_name | ||||
%td.org | %td.org | ||||
= party_name(candidacy.labcoop, candidacy.party.name) | = party_name(candidacy.labcoop, candidacy.party.name) | ||||
- if @election_held | |||||
- if election_held | |||||
%td.right= commify(candidacy.votes) | %td.right= commify(candidacy.votes) | ||||
%td.right= format_percent(candidacy.votes.to_f / @share_denominator * 100) | |||||
%td.right= format_percent(candidacy.votes.to_f / share_denominator * 100) | |||||
- if candidacy.seats == 1 | - if candidacy.seats == 1 | ||||
%td.elected.elected_text="Elected" | %td.elected.elected_text="Elected" | ||||
@@ -72,15 +72,15 @@ | |||||
%td | %td | ||||
%td | %td | ||||
%td | %td | ||||
%td.right= commify(@total_votes) | |||||
%td.right= commify(total_votes) | |||||
%td | %td | ||||
%td | %td | ||||
- if @share_message | |||||
- if share_message | |||||
.warning | .warning | ||||
= @share_message | |||||
= share_message | |||||
- if @total_seats > 1 | |||||
- if total_seats > 1 | |||||
%h2 Votes by party | %h2 Votes by party | ||||
%table | %table | ||||
@@ -96,20 +96,20 @@ | |||||
- count = 0 | - count = 0 | ||||
- @results_by_party.each do |row| | |||||
- results_by_party.each do |row| | |||||
- count += 1 | - count += 1 | ||||
%tr | %tr | ||||
%td.right= count | %td.right= count | ||||
%td{ :style => "background-color: #{row['party_colour'] }" } | %td{ :style => "background-color: #{row['party_colour'] }" } | ||||
%td= row['party_name'] | %td= row['party_name'] | ||||
- if @election_held | |||||
- if election_held | |||||
%td.right.highlight= row['num_seats'] | %td.right.highlight= row['num_seats'] | ||||
- else | - else | ||||
%td.right.highlight — | %td.right.highlight — | ||||
%td.right= row['num_candidates'] | %td.right= row['num_candidates'] | ||||
- if @election_held | |||||
- if election_held | |||||
%td.right= commify(row['total_votes']) | %td.right= commify(row['total_votes']) | ||||
%td.right= format_percent(row['total_votes'].to_f / @total_votes * 100) | |||||
%td.right= format_percent(row['total_votes'].to_f / total_votes * 100) | |||||
%td.right= commify(row['total_votes'] / row['num_candidates']) | %td.right= commify(row['total_votes'] / row['num_candidates']) | ||||
- else | - else | ||||
%td.right — | %td.right — | ||||
@@ -120,48 +120,48 @@ | |||||
%td | %td | ||||
%td | %td | ||||
%td | %td | ||||
- if @election_held | |||||
%td.right.highlight= @total_seats | |||||
- if election_held | |||||
%td.right.highlight= total_seats | |||||
- else | - else | ||||
%td.right.highlight | %td.right.highlight | ||||
%td.right= @total_candidates | |||||
%td.right= commify(@total_votes) | |||||
%td.right= total_candidates | |||||
%td.right= commify(total_votes) | |||||
%td | %td | ||||
%td | %td | ||||
- if @poll | |||||
- if poll | |||||
%p | %p | ||||
%table | %table | ||||
- if @poll.ballot_papers_issued | |||||
- if poll.ballot_papers_issued | |||||
%tr | %tr | ||||
%td Ballot papers issued | %td Ballot papers issued | ||||
%td.right= commify(@poll.ballot_papers_issued) | |||||
- if @poll.electorate | |||||
%td.right= commify(poll.ballot_papers_issued) | |||||
- if poll.electorate | |||||
%tr | %tr | ||||
%td Electorate | %td Electorate | ||||
%td.right= commify(@poll.electorate) | |||||
- if @poll.turnout_percent > 0 | |||||
%td.right= commify(poll.electorate) | |||||
- if poll.turnout_percent > 0 | |||||
%tr | %tr | ||||
%td Turnout | %td Turnout | ||||
%td.right= sprintf("%.0f%%", @poll.turnout_percent) | |||||
%td.right= sprintf("%.0f%%", poll.turnout_percent) | |||||
-# Show this table conditionally as sometimes we have electorate data but no | -# Show this table conditionally as sometimes we have electorate data but no | ||||
-# breakdown of rejected ballot papers | -# breakdown of rejected ballot papers | ||||
- if @poll.rejected_no_official_mark | |||||
- if poll.rejected_no_official_mark | |||||
%h2 Rejected ballot papers | %h2 Rejected ballot papers | ||||
%table | %table | ||||
%tr | %tr | ||||
%td No official mark on the ballot paper | %td No official mark on the ballot paper | ||||
%td.right= commify(@poll.rejected_no_official_mark) | |||||
%td.right= commify(poll.rejected_no_official_mark) | |||||
%tr | %tr | ||||
%td Voting for too many candidates | %td Voting for too many candidates | ||||
%td.right= commify(@poll.rejected_too_many_candidates) | |||||
%td.right= commify(poll.rejected_too_many_candidates) | |||||
%tr | %tr | ||||
%td Voter could be identified by writing or a mark on the ballot paper | %td Voter could be identified by writing or a mark on the ballot paper | ||||
%td.right= commify(@poll.rejected_identifiable_voter) | |||||
%td.right= commify(poll.rejected_identifiable_voter) | |||||
%tr | %tr | ||||
%td Ballot paper unmarked or voter's intention uncertain | %td Ballot paper unmarked or voter's intention uncertain | ||||
%td.right= commify(@poll.rejected_blank_or_uncertain) | |||||
%td.right= commify(poll.rejected_blank_or_uncertain) | |||||
%tr.footer | %tr.footer | ||||
%td | %td | ||||
%td.right= commify(@poll.total_rejected_ballots) | |||||
%td.right= commify(poll.total_rejected_ballots) |