| @@ -4,3 +4,4 @@ | |||
| .bundle/config | |||
| /.ruby-gemset | |||
| /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 | |||
| @@ -8,10 +8,10 @@ | |||
| %th | |||
| %th | |||
| %th turnout | |||
| - @elections.each do |election| | |||
| - elections.each do |election| | |||
| %tr | |||
| %td | |||
| %a{ :href => "/bodies/#{@body.slug}/elections/#{election.d}" }< | |||
| %a{ :href => "/bodies/#{body.slug}/elections/#{election.d}" }< | |||
| = short_date(election.d) | |||
| %td | |||
| = election.kind | |||
| @@ -20,9 +20,9 @@ | |||
| = format_percent(election.turnout_percent) | |||
| %h2 | |||
| = @body.districts_name.capitalize | |||
| = body.districts_name.capitalize | |||
| - @districts.each do |district| | |||
| - districts.each do |district| | |||
| %p | |||
| %a{ :href => "/bodies/#{@body.slug}/#{@body.districts_name}/#{district.slug}" } | |||
| %a{ :href => "/bodies/#{body.slug}/#{body.districts_name}/#{district.slug}" } | |||
| = district.name | |||
| @@ -2,7 +2,7 @@ | |||
| %a{ :href => "/candidates" } | |||
| « All candidates | |||
| %h1= @page_title = @candidate.name | |||
| %h1= page_title = candidate.name | |||
| %h2 Elections contested | |||
| @@ -17,7 +17,7 @@ | |||
| %th position | |||
| %th | |||
| - @candidacies.each do |ccy| | |||
| - candidacies.each do |ccy| | |||
| %tr | |||
| %td{ :style => "background-color: #{ccy['party_colour']}" } | |||
| %td | |||
| @@ -46,6 +46,6 @@ | |||
| %p | |||
| 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 | |||
| for details. | |||
| @@ -1,21 +1,21 @@ | |||
| %h1= @page_title = "Candidates" | |||
| %h1= page_title = "Candidates" | |||
| %nav.letter_index | |||
| - ("A".."Z").each do |letter| | |||
| %a{ :href => "##{letter}" }< | |||
| = letter | |||
| - @first_letter = '' | |||
| - first_letter = '' | |||
| %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 | |||
| %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 | |||
| %tr | |||
| %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 | |||
| %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 | |||
| = @district.name | |||
| = district.name | |||
| 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 | |||
| = long_date(@election.d) | |||
| = long_date(election.d) | |||
| %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 | |||
| %td{ :style => "background-color: #{c.party.colour}" } | |||
| %td.candidate_name.fn | |||
| @@ -42,12 +42,12 @@ | |||
| %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 == [] | |||
| %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 | |||
| = 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 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 | |||
| %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 | |||
| - @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 | |||
| = @election.body.name | |||
| = election.body.name | |||
| 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 | |||
| = @election.body.name | |||
| = election.body.name | |||
| election | |||
| » | |||
| %h1 | |||
| = @election.body.name | |||
| = @election.kind | |||
| = election.body.name | |||
| = election.kind | |||
| %br | |||
| = long_date(@election.d) | |||
| = long_date(election.d) | |||
| -# 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 | |||
| We don't have the results for this election yet. | |||
| %p= @polling_station | |||
| -# %p= polling_station | |||
| %p= @election.reason | |||
| %p= election.reason | |||
| %p | |||
| = @election.candidacies.count | |||
| = "candidate".pluralize(@election.candidacies.count) | |||
| - if @election_held | |||
| = election.candidacies.count | |||
| = "candidate".pluralize(election.candidacies.count) | |||
| - if election_held | |||
| contested | |||
| - else | |||
| will be contesting | |||
| -# 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 | |||
| = @total_districts | |||
| = @election.body.district_name.pluralize(@total_districts) | |||
| = total_districts | |||
| = election.body.district_name.pluralize(total_districts) | |||
| in Sutton. | |||
| - if @election_held | |||
| - if election_held | |||
| %table | |||
| %tr.header | |||
| @@ -69,69 +69,69 @@ | |||
| %th.highlight seats won | |||
| %th votes | |||
| %th % votes | |||
| - if @total_seats > 1 | |||
| - if total_seats > 1 | |||
| %th % seats | |||
| %th votes per seat | |||
| %th candidates | |||
| %th votes per candidate | |||
| -# | |||
| %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 | |||
| %td{ :style => "background-color: #{row.colour}" } | |||
| %td.data_party= row.name | |||
| %td.data_seats.right.highlight= row.seatz | |||
| %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 | |||
| - if row.seatz > 0 | |||
| = commify(row.votez / row.seatz) | |||
| - else | |||
| — | |||
| %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= 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 | |||
| %td | |||
| %td | |||
| %td.right.highlight= @total_seats | |||
| %td.right= commify(@total_votes) | |||
| %td.right.highlight= total_seats | |||
| %td.right= commify(total_votes) | |||
| %td | |||
| - if @total_seats > 1 | |||
| - if total_seats > 1 | |||
| %td | |||
| %td | |||
| %td.right= commify(@election.candidacies.count) | |||
| %td.right= commify(election.candidacies.count) | |||
| %td | |||
| - if @election.ballot_papers_issued | |||
| - if election.ballot_papers_issued | |||
| %table | |||
| %tr | |||
| %td Electorate | |||
| %td.right= commify(@election.electorate) | |||
| %td.right= commify(election.electorate) | |||
| %tr | |||
| %td Ballot papers issued | |||
| %td.right= commify(@election.ballot_papers_issued) | |||
| %td.right= commify(election.ballot_papers_issued) | |||
| %tr | |||
| %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 | |||
| = "Candidate".pluralize(@total_seats) | |||
| = "Candidate".pluralize(total_seats) | |||
| elected | |||
| %table | |||
| - @election.polls.each do |p| | |||
| - election.polls.each do |p| | |||
| %tr | |||
| %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.successful_candidacies.each do |sc| | |||
| %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 | |||
| %table | |||
| - @future_elections.each do |election| | |||
| - future_elections.each do |election| | |||
| %tr | |||
| %td | |||
| %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | |||
| @@ -20,12 +21,12 @@ | |||
| %td | |||
| = election.kind | |||
| - if @past_elections.size > 0 | |||
| - if past_elections.size > 0 | |||
| %h2 Past elections | |||
| %table | |||
| - @past_elections.each do |election| | |||
| - past_elections.each do |election| | |||
| %tr | |||
| %td | |||
| %a{ :href => "/bodies/#{election.body.slug}/elections/#{election.d}" } | |||
| @@ -2,7 +2,7 @@ | |||
| %html | |||
| %head | |||
| %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 => '/print.css', :media => 'print' } | |||
| %meta{ :name => 'referrer', :content => 'no-referrer' } | |||
| @@ -28,10 +28,11 @@ | |||
| %a{ :href => '/about' } About | |||
| #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 | |||
| @@ -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 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 | |||
| - 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 | |||
| %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 | |||
| %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 | |||
| We don't have the results for this election yet. | |||
| @@ -44,7 +44,7 @@ | |||
| %th | |||
| - count = 0 | |||
| - @candidacies.each do |candidacy| | |||
| - candidacies.each do |candidacy| | |||
| - count += 1 | |||
| %tr.vcard | |||
| %td= count | |||
| @@ -54,9 +54,9 @@ | |||
| = candidacy.candidate.short_name | |||
| %td.org | |||
| = party_name(candidacy.labcoop, candidacy.party.name) | |||
| - if @election_held | |||
| - if election_held | |||
| %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 | |||
| %td.elected.elected_text="Elected" | |||
| @@ -72,15 +72,15 @@ | |||
| %td | |||
| %td | |||
| %td | |||
| %td.right= commify(@total_votes) | |||
| %td.right= commify(total_votes) | |||
| %td | |||
| %td | |||
| - if @share_message | |||
| - if share_message | |||
| .warning | |||
| = @share_message | |||
| = share_message | |||
| - if @total_seats > 1 | |||
| - if total_seats > 1 | |||
| %h2 Votes by party | |||
| %table | |||
| @@ -96,20 +96,20 @@ | |||
| - count = 0 | |||
| - @results_by_party.each do |row| | |||
| - results_by_party.each do |row| | |||
| - count += 1 | |||
| %tr | |||
| %td.right= count | |||
| %td{ :style => "background-color: #{row['party_colour'] }" } | |||
| %td= row['party_name'] | |||
| - if @election_held | |||
| - if election_held | |||
| %td.right.highlight= row['num_seats'] | |||
| - else | |||
| %td.right.highlight — | |||
| %td.right= row['num_candidates'] | |||
| - if @election_held | |||
| - if election_held | |||
| %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']) | |||
| - else | |||
| %td.right — | |||
| @@ -120,48 +120,48 @@ | |||
| %td | |||
| %td | |||
| %td | |||
| - if @election_held | |||
| %td.right.highlight= @total_seats | |||
| - if election_held | |||
| %td.right.highlight= total_seats | |||
| - else | |||
| %td.right.highlight | |||
| %td.right= @total_candidates | |||
| %td.right= commify(@total_votes) | |||
| %td.right= total_candidates | |||
| %td.right= commify(total_votes) | |||
| %td | |||
| %td | |||
| - if @poll | |||
| - if poll | |||
| %p | |||
| %table | |||
| - if @poll.ballot_papers_issued | |||
| - if poll.ballot_papers_issued | |||
| %tr | |||
| %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 | |||
| %td Electorate | |||
| %td.right= commify(@poll.electorate) | |||
| - if @poll.turnout_percent > 0 | |||
| %td.right= commify(poll.electorate) | |||
| - if poll.turnout_percent > 0 | |||
| %tr | |||
| %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 | |||
| -# breakdown of rejected ballot papers | |||
| - if @poll.rejected_no_official_mark | |||
| - if poll.rejected_no_official_mark | |||
| %h2 Rejected ballot papers | |||
| %table | |||
| %tr | |||
| %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 | |||
| %td Voting for too many candidates | |||
| %td.right= commify(@poll.rejected_too_many_candidates) | |||
| %td.right= commify(poll.rejected_too_many_candidates) | |||
| %tr | |||
| %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 | |||
| %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 | |||
| %td | |||
| %td.right= commify(@poll.total_rejected_ballots) | |||
| %td.right= commify(poll.total_rejected_ballots) | |||