From 320feb3eae1a5eb3beea38a381ff153c5e6eb190 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Sat, 4 Mar 2023 14:09:16 +0900 Subject: Add applicant table --- src/xhtml.cr | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/xhtml.cr (limited to 'src/xhtml.cr') diff --git a/src/xhtml.cr b/src/xhtml.cr new file mode 100644 index 0000000..ea4f87e --- /dev/null +++ b/src/xhtml.cr @@ -0,0 +1,190 @@ +# XHTML generation +# Copyright (C) 2023 Nguyễn Gia Phong +# +# This file if part of hybring. +# +# Hybring is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Hybring is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with hybring. If not, see . + +require "uri" +require "xml" + +require "./sqlite" + +CSS = " + html { + margin: auto; + max-width: 72ch; + } + body { margin-bottom: 2rem } + h1, h2, h3, h4, h5, h6 { margin: 1ex 0 } + form { + display: grid; + grid-template-columns: max-content 1fr 0; + } + form label { margin-right: 1ch } + form input { margin-bottom: 1ex } + .error { color: red } + " + +class Page + def initialize(static_dir : String, static_url : String, api_url : String, + db : Database) + Dir.mkdir_p static_dir + @static_file = Path[static_dir] / "index.xhtml" + @static_url = static_url + @static_host = URI.parse(static_url).host + @api_url = api_url + @db = db + end + + def criteria(xml) + xml.element "h2" do xml.text "criteria" end + xml.element "p" do + xml.text "We accept pretty much any site" + xml.text " served under an OpenNIC domain" + xml.text " meeting the following requirements." + end + xml.element "ul" do + xml.element "li" do xml.text "Family-friendly content" end + xml.element "li" do xml.text "No violence incitation or doxing" end + xml.element "li" do xml.text "No user tracking" end + xml.element "li" do + xml.text "ICANN counterpart accessible via HTTPS" + end + xml.element "li" do + xml.text "Both linking to neighboring members" + end + end + xml.element "p" do + xml.text "Note that the two sites needn't be the same, as long as" + xml.text " they represent the same entity, e.g. person or organization." + xml.text " The clear net site is for serving visitors" + xml.text " without OpenNIC access or preferring secure connections." + end + end + + def input(xml, name, label, hint, error, value) + if error + xml.element "span" + xml.element "span", class: "error" do xml.text error end + xml.element "br" + end + xml.element "label", for: name do xml.text label end + xml.element "input", name: name, placeholder: hint, value: value, + required: "required" + xml.element "br" + end + + def form(xml, errors = {} of String => String, + params = {} of String => String) + xml.element "p" do xml.text "Then, please fill out the form below." end + nick = params.fetch("nick", nil) + xml.element "form", action: @api_url, method: "POST" do + input xml, "nick", "Nickname", "digits or lowercase letters", + errors.fetch("nick", nil), nick || "" + input xml, "opennic", "OpenNIC URL", "e.g. http://example.null", + errors.fetch("opennic", nil), params.fetch("opennic", "") + input xml, "icann", "ICANN URL", "e.g. https://example.net", + errors.fetch("icann", nil), params.fetch("icann", "") + xml.element "span" do + xml.element "input", type: "hidden", name: "host", value: @static_host + end + xml.element "input", type: "submit", value: "Let me in!" + xml.element "br" + end + + xml.element "p" do + xml.text "Your application is pending for approval." + xml.text " Please subscribe to this " + xml.element "a", href: "#{@static_url}/#{nick}.atom" do + xml.text "web feed" + end + xml.text " for further instructions." + end if nick && errors.empty? + end + + def member(xml, nick, opennic, icann) + xml.element "h3" do xml.text nick end + xml.text "OpenNIC: " + xml.element "a", href: opennic do xml.text opennic end + xml.element "br" + xml.text "ICANN: " + xml.element "a", href: icann do xml.text icann end + xml.element "br" + end + + def build(errors = {} of String => String, + params = {} of String => String) : String + XML.build encoding: "UTF-8", indent: " " do |xml| + xml.element "html", xmlns: "http://www.w3.org/1999/xhtml", lang: "en" do + xml.element "head" do + xml.element "meta", name: "viewport", + content: "width=device-width,initial-scale=1.0" + xml.element "link", rel: "icon", href: "data:," + xml.element "style" do xml.text CSS end + xml.element "title" do xml.text "le cercle libre" end + end + xml.element "body" do + xml.element "h1" do xml.text "le cercle libre" end + xml.element "p" do + xml.text "The Free Circle is a web ring for sites" + xml.text " with an OpenNIC domain." + end + criteria xml + + xml.element "h2" do xml.text "members" end + @db.members.each_value do |nick, opennic, icann| + member xml, nick, opennic, icann + end + + xml.element "h2" do xml.text "joining" end + xml.element "p" do + xml.text "First, add " + xml.element "a", + href: "https://html.spec.whatwg.org/#the-a-element" do + xml.text "anchors" + end + xml.text " refering to the following neighbors to your sites" + xml.text " on both OpenNIC and ICANN domains." + xml.text " Your neighbors will change as people come and go," + xml.text " so you will be given an Atom feed with instructions" + xml.text " to keep the hyperlinks up to date." + end + xml.element "ul" do + xml.element "li" do + xml.text "Left: " + _, left, _ = @db.members.last_value + xml.element "a", href: left do xml.text left end + end + xml.element "li" do + xml.text "Right: " + _, right, _ = @db.members.first_value + xml.element "a", href: right do xml.text right end + end + end + form xml, errors, params + + xml.element "h2" do xml.text "applicants" end + @db.applicants.each_value do |nick, opennic, icann| + member xml, nick, opennic, icann + end + end + end + end + end + + def write + File.write @static_file, self.build + end +end -- cgit 1.4.1