From fc9d0042c0c0674c398c26340cee98a2489429b0 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Wed, 31 Jul 2019 18:37:46 +0200 Subject: [PATCH 1/4] Remove .htaccess from PHP age --- .htaccess | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .htaccess diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 403e132..0000000 --- a/.htaccess +++ /dev/null @@ -1,33 +0,0 @@ - -php_flag display_errors Off -php_flag log_errors On -php_value error_log syslog - -php_flag safe_mode On -php_flag safe_mode_gid On -php_value open_basedir /var/www/board -php_value safe_mode_exec_dir /var/empty - - - - Order Deny,Allow - Deny from all - - - - - - - # these files require authentication - - SSLOptions +OptRenegotiate +StdEnvVars +ExportCertData - SSLUserName SSL_CLIENT_S_DN_Email - SSLVerifyClient require -# -# RewriteEngine on -# RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS -# RewriteRule .? - [F] -# ErrorDocument 403 "You need a client side certificate issued by CAcert to access this url" -# - - From 96089d49df266182ee838aff972f293a5c01f8e3 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 2 Aug 2019 22:42:09 +0200 Subject: [PATCH 2/4] Improve documentation - fix parameter name in curl invocation - add default port of Python aoismtpd --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a3dbd4..ab8ccc0 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ use `openssl` to create a self signed server certificate and retrieve the CAcert ```shell script openssl req -new -newkey rsa:2048 -keyout server.key -x509 -out server.crt -subj '/CN=localhost' -curl -O cacert_class3.pem http://www.cacert.org/certs/class3_X0E.crt +curl -o cacert_class3.pem http://www.cacert.org/certs/class3_X0E.crt ``` It is advisable to have a local mail setup that intercepts outgoing email or to use email addresses that you control. @@ -91,8 +91,7 @@ Parameter | Description | How to get a valid value `csrf_key` | A base64 encoded random byte value of at least 32 bytes used to encrypt [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention) tokens | see [Generating random byte values](#generating-random-byte-values) below `base_url` | The base URL of your application instance (production value is https://motions.cacert.org) | use https://localhost:8443 `mail_server`.`host` | Mail server host (production value is `localhost`) | `localhost` -`mail_server`.`port` | Mail server TCP port (production value is `25` | see [how to setup a debugging SMTP server](#debugging-smtp-server) below and choose the port of that - +`mail_server`.`port` | Mail server TCP port (production value is `25` | see [how to setup a debugging SMTP server](#debugging-smtp-server) below and choose the port of that (default `8025`) ### Generating random byte values ```shell script From 1f32b6d25b5e951ecfb157e0698ee17d5e71136c Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 2 Aug 2019 23:55:51 +0200 Subject: [PATCH 3/4] Add icon images --- .../static/images/CAcert-logo-colour.svg | 46 ++++++++++++++++++ boardvoting/static/images/favicon.ico | Bin 0 -> 3638 bytes 2 files changed, 46 insertions(+) create mode 100644 boardvoting/static/images/CAcert-logo-colour.svg create mode 100644 boardvoting/static/images/favicon.ico diff --git a/boardvoting/static/images/CAcert-logo-colour.svg b/boardvoting/static/images/CAcert-logo-colour.svg new file mode 100644 index 0000000..0d8e071 --- /dev/null +++ b/boardvoting/static/images/CAcert-logo-colour.svg @@ -0,0 +1,46 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/boardvoting/static/images/favicon.ico b/boardvoting/static/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3c9c9c2cdbd5c852af69adc49337f34cefea4323 GIT binary patch literal 3638 zcmeH}X;fBK7svmYltY7q1NiGwVyNWbI(5K-24208<4{Q3>yZi z7|R2y)KXD--47fDIMSFJb;T*-upDSmEOM`_Kela*rlPhy7X_)8QC)Hkb(PoQad;W3 zim$@Ud?oId=b^c-906yxA?&C9i1IPTvnLPnyz3b*p8gKZ*8(qJ_Toi%7h*10!EB8Z z+M4guoHq3Iyg)BmdV~j_w6!4a7aN$b9gCDu7kcI;UXj@w&qDk~TO3bT^%9Z@nfwBD=2 zlSeIRzFUR>hpl+fRD)NqUZUgi1Dv;6kCysMJbu`Oww5}CoZW-Yr;l(Y&>j(9KO*|P zCCz;W)77J4y-^K4FS=p5egbT_&VZS|GEzdEks0Fyt8Z0tYP&j4Zkdj<`~{O<<-`8UA-*`n~(uqBgbX^dLQ^UCU@27LIQKt*M~lF}kg{(a$X zHDT$OgT~EJcuSbArL{tMQ&0GUB78D-nmA4P`129M0x6>6i0Pk=78de?@PX9VoGJ{Q zD@@^632#t;B+ri#J{`Y&I6qYQ`dxm`Ol5vBJwAlz=W&9{WNlpqo}VZP6KJZO{IU_c z<1~4GF?1GDpXcBCNL8x;ub;pAhD4oJAzMuLyUq@zPJijsTt@mN>ZXm+6iMGiEemus zMx6f%ba!!Y!Aq*on9P;*T4t?}n$m2v zKe&hDYY}kW$Kz%ugP+|dFqt_rn3tr(?xg3UewXDXP`s0eg z8D~kKOLODURC^0uolhjq7d13H{sMByyv+0{b{c|Rcj5H+vn56(k_L;M$WOjRdr?9` zN-*tV4ecRIVopk^GurPrNQ_7gbA$7qMJUP$$Ay!ID5hFuR+Nt!j+1V?9n>a1c;Z%0 z46#B-;y_bvDPsJr5lhz9`4r^^iKOc@;c2RiAeWs8CQGu4VbU}2ylv8#wU<-BJx#VtUj_fgbSZM{JiPuuTHY`R8#x_EjE8f!}M+q1_M zvjf?2=h50wNpVi$3Yo~4{G-Yg}}V&(c}r|7zn+LdCu3q}1;x}w_w!DQ_ncTb zM&hT)N{h8Bw00P=c^&b+8EN5X;kuu`!7PRnvWDs+V)sn@!H_5%?kK09QFr|D%%t;(f<{&Bf%@bK`-eMeHIb_BJ9oX={g6>>i=cd)4o)z;R& zPGfO~jNPO5c*e~0Ifd^N65=5u-R8L?bv#`No1!B}eYS~l{~F!q^(osMmd^7TWO5Pk6@Ygt;HP z3}4sh<{B6qKiGM!YGkjYffOxPiR z?5iVlxhw1f`G291iz4?}Rk<_Edo$cjnERlSZ*O#)wvBsNN49FAFD=hj?<>Bn$e8s} zHseD!eW%8?y3HQ7yNuGpDpH1sFKWMx<0AE0#aOo+z8e*1p4#x!=@C)Y>r2)5a(BfO zy;n$qWMS-Ze2H%|-Jgv{!8dsvCmw6Q=&wIdEzZCz{ZrRSx_@zK*}$qs8hf91PbKx1 zIN^1X{K`v5XM9clO_G~2`(OLrT*^eZg-`|e3U^f&+c_1`Wie{#Y90l~@W1ONa4 literal 0 HcmV?d00001 From ea9641cfb136152c4a314077592d7e1bc786d5fb Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 3 Aug 2019 01:39:55 +0200 Subject: [PATCH 4/4] Refine HTML layout This commit improves the page structure and unifies the layout. Some reusable parts of the HTML code have been moved into page_fragments.html. --- boardvoting.go | 16 +-- boardvoting/templates/create_motion_form.html | 112 ++++++++--------- boardvoting/templates/denied.html | 30 +++-- boardvoting/templates/direct_vote_form.html | 34 ++--- boardvoting/templates/edit_motion_form.html | 112 ++++++++--------- boardvoting/templates/footer.html | 16 +-- boardvoting/templates/header.html | 35 ++++-- boardvoting/templates/motion.html | 17 +-- boardvoting/templates/motion_fragments.html | 116 +++++++++--------- boardvoting/templates/motions.html | 71 +++++------ boardvoting/templates/page_fragments.html | 20 +++ boardvoting/templates/proxy_vote_form.html | 71 +++++------ .../templates/withdraw_motion_form.html | 29 ++--- 13 files changed, 342 insertions(+), 337 deletions(-) create mode 100644 boardvoting/templates/page_fragments.html diff --git a/boardvoting.go b/boardvoting.go index 7228849..e58bee1 100644 --- a/boardvoting.go +++ b/boardvoting.go @@ -219,7 +219,9 @@ func motionListHandler(w http.ResponseWriter, r *http.Request) { templateContext.PrevPage = params.Page - 1 } - renderTemplate(w, r, []string{"motions.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext) + renderTemplate(w, r, []string{ + "motions.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html", + }, templateContext) } func motionHandler(w http.ResponseWriter, r *http.Request) { @@ -252,7 +254,7 @@ func motionHandler(w http.ResponseWriter, r *http.Request) { } templateContext.Decision = decision templateContext.PageTitle = fmt.Sprintf("Motion %s: %s", decision.Tag, decision.Title) - renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "header.html", "footer.html"}, templateContext) + renderTemplate(w, r, []string{"motion.html", "motion_fragments.html", "page_fragments.html", "header.html", "footer.html"}, templateContext) } func singleDecisionHandler(w http.ResponseWriter, r *http.Request, tag string, handler func(http.ResponseWriter, *http.Request)) { @@ -326,7 +328,7 @@ func (a *withDrawMotionAction) Handle(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed) return } - templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html"} + templates := []string{"withdraw_motion_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"} var templateContext struct { PageTitle string Decision *DecisionForDisplay @@ -366,7 +368,7 @@ func (h *newMotionHandler) Handle(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed) } - templates := []string{"create_motion_form.html", "header.html", "footer.html"} + templates := []string{"create_motion_form.html", "page_fragments.html", "header.html", "footer.html"} var templateContext struct { Form NewDecisionForm PageTitle string @@ -428,7 +430,7 @@ func (a editMotionAction) Handle(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusPreconditionFailed), http.StatusPreconditionFailed) return } - templates := []string{"edit_motion_form.html", "header.html", "footer.html"} + templates := []string{"edit_motion_form.html", "page_fragments.html", "header.html", "footer.html"} var templateContext struct { Form EditDecisionForm PageTitle string @@ -560,7 +562,7 @@ func (h *directVoteHandler) Handle(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/motions/", http.StatusMovedPermanently) default: - templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html"} + templates := []string{"direct_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"} var templateContext struct { Decision *DecisionForDisplay VoteChoice VoteChoice @@ -601,7 +603,7 @@ func (h *proxyVoteHandler) Handle(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html"} + templates := []string{"proxy_vote_form.html", "header.html", "footer.html", "motion_fragments.html", "page_fragments.html"} var templateContext struct { Form ProxyVoteForm Decision *DecisionForDisplay diff --git a/boardvoting/templates/create_motion_form.html b/boardvoting/templates/create_motion_form.html index ef72ec6..2d8db12 100644 --- a/boardvoting/templates/create_motion_form.html +++ b/boardvoting/templates/create_motion_form.html @@ -1,74 +1,66 @@ {{ template "header.html" . }} -
-
- -
-
-
-
-
+{{ template "return_header" . }} +
+ {{ csrfField }} -
-
-
- - (generated on submit) -
-
- - {{ .Voter.Name }} -
-
- - (auto filled to current date/time) -
+
+
+
+ + (generated on submit)
-
- - +
+ + {{ .Voter.Name }}
-
- - +
+ + (auto filled to current date/time)
-
-
- - -
-
- - -
+
+
+ + +
+
+ + +
+
+
+ +
- {{ with .Form.Errors }} +
+ + +
+
+ {{ with .Form.Errors }}
{{ with .Title }}

{{ . }}

{{ end }} {{ with .Content }}

{{ . }}

{{ end }} {{ with .VoteType }}

{{ . }}

{{ end }} {{ with .Due }}

{{ . }}

{{ end }}
- {{ end }} - -
- -
+ {{ end }} + +
+
{{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/denied.html b/boardvoting/templates/denied.html index 53bb364..fc89505 100644 --- a/boardvoting/templates/denied.html +++ b/boardvoting/templates/denied.html @@ -1,17 +1,23 @@ {{ template "header.html" . }} -
-
-
You are not authorized to act here!
-

If you think this is in error, please contact the administrator.

-

If you don't know who that is, it is definitely not an error ;)

- {{ if .Emails }} -

The following addresses were present in your certificate:

-

    - {{ range .Emails }} -
  • {{ . }}
  • +
    +
    + +
    +
    You are not authorized to act here!
    +

    If you think this is in error, please contact the administrator.

    +

    If you don't know who that is, it is definitely not an error ;)

    + {{ if .Emails }} +

    The following addresses were present in your certificate:

    +

    + {{ range .Emails }} +
    + +
    {{ . }}
    +
    + {{ end }} +
    {{ end }} -
- {{ end }} +
{{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/direct_vote_form.html b/boardvoting/templates/direct_vote_form.html index 66e21a9..fff77eb 100644 --- a/boardvoting/templates/direct_vote_form.html +++ b/boardvoting/templates/direct_vote_form.html @@ -1,31 +1,23 @@ {{ template "header.html" . }} -
-
- -
-
+{{ template "return_header" . }} {{ with .Decision }} -
- {{ template "motion_fragment" . }} + {{ template "motion_fragment" . }}
-
{{ end }}
-{{ csrfField }} + {{ csrfField }}
- {{ if eq 1 .VoteChoice }} - - {{ else if eq -1 .VoteChoice }} - - {{ else }} - - {{ end }} + {{ if eq 1 .VoteChoice }} + + {{ else if eq -1 .VoteChoice }} + + {{ else }} + + {{ end }}
{{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/edit_motion_form.html b/boardvoting/templates/edit_motion_form.html index 845442d..1798b27 100644 --- a/boardvoting/templates/edit_motion_form.html +++ b/boardvoting/templates/edit_motion_form.html @@ -1,72 +1,66 @@ {{ template "header.html" . }} - -
-
-
-
-
- -
- - {{ .Voter.Name }} -
-
- - {{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }} -
+{{ template "return_header" . }} +
+ + {{ csrfField }} +
+
+ -
- - +
+ + {{ .Voter.Name }}
-
- - +
+ + {{ .Form.Decision.Proposed|date "2006-01-02 15:04:05 UTC" }}
-
-
- - -
-
- - -
+
+
+ + +
+
+ + +
+
+
+ +
- {{ with .Form.Errors }} +
+ + +
+
+ {{ with .Form.Errors }}
{{ with .Title }}

{{ . }}

{{ end }} {{ with .Content }}

{{ . }}

{{ end }} {{ with .VoteType }}

{{ . }}

{{ end }} {{ with .Due }}

{{ . }}

{{ end }}
- {{ end }} - -
- -
+ {{ end }} + +
+
{{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/footer.html b/boardvoting/templates/footer.html index fa873e5..da6699c 100644 --- a/boardvoting/templates/footer.html +++ b/boardvoting/templates/footer.html @@ -1,12 +1,12 @@ {{ define "footer.html" }} -
- +
+ {{ end }} \ No newline at end of file diff --git a/boardvoting/templates/header.html b/boardvoting/templates/header.html index d4f9621..acf8d18 100644 --- a/boardvoting/templates/header.html +++ b/boardvoting/templates/header.html @@ -7,20 +7,35 @@ + - + +
+
+
+ CAcert +
+
+

+ {{ template "pagetitle" . }} + {{ if .Voter }} +
Authenticated as {{ .Voter.Name }} <{{ .Voter.Reminder }}> +
{{ end }} +

+
+
+
-

{{ template "pagetitle" . }}{{ if .Voter }}
Authenticated as {{ .Voter.Name }} <{{ .Voter.Reminder }}>
{{ end }}

{{ with .Flashes }} -
- -
- {{ range . }} -
{{ . }}
- {{ end }} +
+
+ +
+ {{ range . }} +
{{ . }}
+ {{ end }} +
{{ end }} -
-
{{ end }} diff --git a/boardvoting/templates/motion.html b/boardvoting/templates/motion.html index e78a955..a4c3a30 100644 --- a/boardvoting/templates/motion.html +++ b/boardvoting/templates/motion.html @@ -1,19 +1,20 @@ {{ template "header.html" . }} {{ $voter := .Voter }} -
-
- +
+
{{ with .Decision }} -
{{ template "motion_fragment" . }} {{ if $voter }}{{ template "motion_actions" . }}{{ end }}
-
{{ end}} {{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/motion_fragments.html b/boardvoting/templates/motion_fragments.html index 96a1938..876e586 100644 --- a/boardvoting/templates/motion_fragments.html +++ b/boardvoting/templates/motion_fragments.html @@ -1,64 +1,68 @@ {{ define "motion_fragment" }} -{{ .Status|toString|title }} -{{ .Modified|date "2006-01-02 15:04:05 UTC" }} -

{{ .Tag }}: {{ .Title }}

-

{{ wrap 76 .Content | nl2br }}

- - - - - - - - - - - - - - - - - + + +
Due{{.Due|date "2006-01-02 15:04:05 UTC"}}
Proposed{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})
Vote type:{{ .VoteType|toString|title }}
Votes: -
-
Aye -
{{.Ayes}}
+ {{ .Status|toString|title }} + {{ .Modified|date "2006-01-02 15:04:05 UTC" }} +

{{ .Tag }}: {{ .Title }}

+

{{ wrap 76 .Content | nl2br }}

+ + + + + + + + + + + + + + + + + - - -
Due{{.Due|date "2006-01-02 15:04:05 UTC"}}
Proposed{{.Proposer}} ({{.Proposed|date "2006-01-02 15:04:05 UTC"}})
Vote type:{{ .VoteType|toString|title }}
Votes: +
+
Aye +
{{.Ayes}}
+
+
Naye +
{{.Nayes}}
+
+
Abstain +
{{.Abstains}}
+
-
Naye -
{{.Nayes}}
-
-
Abstain -
{{.Abstains}}
-
- - {{ if .Votes }} -
- {{ range .Votes }} -
{{ .Name }}: {{ .Vote.Vote }}
+ {{ if .Votes }} +
+ {{ range .Votes }} +
{{ .Name }}: {{ .Vote.Vote }}
+ {{ end }} +
+ Hide Votes + {{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }} + Show Votes {{ end }} -
- Hide Votes - {{ else if or ((ne 0 .Ayes) (ne 0 .Nayes) (ne 0 .Abstains)) }} - Show Votes - {{ end }} -
+
{{ end }} -{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey -{{ end }}{{ end }} +{{ define "status_class" }}{{ if eq . 0 }}blue{{ else if eq . 1 }}green{{ else if eq . -1 }}red{{ else if eq . -2 }}grey{{ end }}{{ end }} {{ define "motion_actions" }} -{{ if eq .Status 0 }} - Aye - Naye - Abstain - Proxy Vote - Modify - Withdraw -{{ end }} + {{ if eq .Status 0 }} + Aye + Naye + + Abstain + Proxy + Vote + Modify + + Withdraw + {{ end }} {{ end }} diff --git a/boardvoting/templates/motions.html b/boardvoting/templates/motions.html index 625dc57..159cda5 100644 --- a/boardvoting/templates/motions.html +++ b/boardvoting/templates/motions.html @@ -1,52 +1,45 @@ {{ template "header.html" . }} {{ $voter := .Voter }} -
-
- - {{ if $voter }}New motion{{ end }} - {{ if .PrevPage -}} - newer - {{- end }} - {{ if .NextPage -}} - older - {{- end }} +{{ $page := . }} +
+
{{ if .Decisions }} + {{ range .Decisions }} -
- {{ template "motion_fragment" . }} - {{ if $voter }}{{ template "motion_actions" . }}{{ end }} + {{ template "motion_fragment" . }} + {{ if $voter }}{{ template "motion_actions" . }}{{ end }}
-
{{ end }} -
-
-{{ if $voter }}New motion{{ end }} -{{ if .PrevPage -}} - - newer -{{- end }} -{{ if .NextPage -}} - - older -{{- end }} + -
{{ else }} - {{ if .Params.Flags.Unvoted }} -

There are no motions requiring a vote from you.

- {{ else }} -

There are no motions in the system yet.

- {{ end }} +
+
+ +
+
No motions available
+ {{ if .Params.Flags.Unvoted }} +

There are no motions requiring a vote from you.

+ {{ else }} +

There are no motions in the system yet.

+ {{ end }} +
+
+
{{ end }} {{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/page_fragments.html b/boardvoting/templates/page_fragments.html new file mode 100644 index 0000000..6a6dedf --- /dev/null +++ b/boardvoting/templates/page_fragments.html @@ -0,0 +1,20 @@ +{{ define "pagination_fragment" }} + {{ if .PrevPage -}} + + newer + + {{- end }} + {{ if .NextPage -}} + + older + + {{- end }} +{{ end }} + +{{ define "return_header" }} +
+ +
+{{ end }} \ No newline at end of file diff --git a/boardvoting/templates/proxy_vote_form.html b/boardvoting/templates/proxy_vote_form.html index 97ae86b..a6ab5ee 100644 --- a/boardvoting/templates/proxy_vote_form.html +++ b/boardvoting/templates/proxy_vote_form.html @@ -1,56 +1,47 @@ {{ template "header.html" . }} +{{ template "return_header" . }} {{ $form := .Form }} -
- -
-
-
+
{{ with .Decision }} {{ template "motion_fragment" . }} - {{ end }} -
+ {{ end }} + {{ csrfField }} -
-
-
- - {{ range .Voters }} + {{ if eq (.Id | print) $form.Voter }} + selected{{ end }}>{{ .Name }} {{ end }} - -
-
- - -
+
-
- - +
+ +
+
+
+ + +
{{ with .Form.Errors }}
- {{ with .Voter }}

{{ . }}

{{ end }} - {{ with .Vote }}

{{ . }}

{{ end }} - {{ with .Justification }}

{{ . }}

{{ end }} + {{ with .Voter }}

{{ . }}

{{ end }} + {{ with .Vote }}

{{ . }}

{{ end }} + {{ with .Justification }}

{{ . }}

{{ end }}
{{ end }} - -
-
-
+ +
+
{{ template "footer.html" . }} \ No newline at end of file diff --git a/boardvoting/templates/withdraw_motion_form.html b/boardvoting/templates/withdraw_motion_form.html index 7b444e7..b549cea 100644 --- a/boardvoting/templates/withdraw_motion_form.html +++ b/boardvoting/templates/withdraw_motion_form.html @@ -1,22 +1,17 @@ {{ template "header.html" . }} -
-
- -
-
+{{ template "return_header" . }} {{ with .Decision }} -
- {{ template "motion_fragment" . }} + {{ template "motion_fragment" . }}
-
{{ end }} -
-{{ csrfField }} -
- -
-
-{{ template "footer.html" . }} +
+
+ {{ csrfField }} +
+ +
+
+
+{{ template "footer.html" . }} \ No newline at end of file