From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id qOKgAWWVf19CeQAA0tVLHw (envelope-from ) for ; Thu, 08 Oct 2020 22:40:37 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id Kbf3OGSVf1/FHQAAbx9fmQ (envelope-from ) for ; Thu, 08 Oct 2020 22:40:36 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 2D21A9402A5 for ; Thu, 8 Oct 2020 22:40:36 +0000 (UTC) Received: from localhost ([::1]:52252 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kQeaR-0004d0-0C for larch@yhetil.org; Thu, 08 Oct 2020 18:40:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42280) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kQeZu-0004ag-P4 for guix-patches@gnu.org; Thu, 08 Oct 2020 18:40:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:50099) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kQeZu-0005yU-Ej for guix-patches@gnu.org; Thu, 08 Oct 2020 18:40:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kQeZu-0004lu-Bq for guix-patches@gnu.org; Thu, 08 Oct 2020 18:40:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43871] [PATCH website] Add community page Resent-From: Julien Lepiller Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 08 Oct 2020 22:40:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 43871 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43871@debbugs.gnu.org X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.160219674318271 (code B ref -1); Thu, 08 Oct 2020 22:40:02 +0000 Received: (at submit) by debbugs.gnu.org; 8 Oct 2020 22:39:03 +0000 Received: from localhost ([127.0.0.1]:33412 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kQeYs-0004kG-8M for submit@debbugs.gnu.org; Thu, 08 Oct 2020 18:39:02 -0400 Received: from lists.gnu.org ([209.51.188.17]:40036) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kQeYl-0004k3-BY for submit@debbugs.gnu.org; Thu, 08 Oct 2020 18:38:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42058) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kQeYk-0004BL-Li for guix-patches@gnu.org; Thu, 08 Oct 2020 18:38:50 -0400 Received: from lepiller.eu ([2a00:5884:8208::1]:47634) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kQeYg-0005p1-Le for guix-patches@gnu.org; Thu, 08 Oct 2020 18:38:50 -0400 Received: from lepiller.eu (localhost [127.0.0.1]) by lepiller.eu (OpenSMTPD) with ESMTP id f596eacb for ; Thu, 8 Oct 2020 22:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=lepiller.eu; h=date:from :to:subject:message-id:mime-version:content-type; s=dkim; bh=q7F CBhzxHL4CnXQK5u1ycvNUOd5hl9n3Vt5gIUUYjXk=; b=CtIEvgwFn0loDhB1Frt pJsAMnjF9E7ga88wiOLm08xk9YatN4623di+lcvVRQTVPPttfffkVJpv7PS1zc8T 080Hf+8gqda3MNNGlD1q95up++DZ1W22kwN7DhMO3lkeP1bXHRhL1gltzW4Q8OF+ t6MYQHhEjXTlRqU3Hpb4VEXa3JyQDZjaq/8D4aCSyhRLpsgo9SxVDI9j9A8wt0wK u3Yqf84ebkv1vLaMnO6ibkE27ViD7jfg8vmjMuvvRkoLEk499lm83fYyjKEJASll T5EtWVRtKhDt0YVFSqzO8ITyOmyt76KSk7NZsBFTZVWX1sWhB57JTDA8eFp5ikhH UKA== Received: by lepiller.eu (OpenSMTPD) with ESMTPSA id 91d7e2c1 (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO) for ; Thu, 8 Oct 2020 22:38:40 +0000 (UTC) Date: Fri, 9 Oct 2020 00:38:23 +0200 From: Julien Lepiller Message-ID: <20201009003823.0a15114b@tachikoma> X-Mailer: Claws Mail 3.17.6 (GTK+ 2.24.32; x86_64-unknown-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/o2utkfO_tuoCH6ZT8ICJd0W" Received-SPF: pass client-ip=2a00:5884:8208::1; envelope-from=julien@lepiller.eu; helo=lepiller.eu X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: 0 X-Spam_score: -0.1 X-Spam_bar: / X-Spam_report: (-0.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, PDS_OTHER_BAD_TLD=1.999, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: 0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: 2.0 (++) X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=fail (rsa verify failed) header.d=lepiller.eu header.s=dkim header.b=CtIEvgwF; dmarc=fail reason="SPF not aligned (relaxed)" header.from=lepiller.eu (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Spam-Score: 0.59 X-TUID: iobL3zbT9SeP --MP_/o2utkfO_tuoCH6ZT8ICJd0W Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi Guix! This patch aims at adding a new page on the website that lists external resources that talk about guix (conference talks, blog posts and even academic papers). --MP_/o2utkfO_tuoCH6ZT8ICJd0W Content-Type: text/x-patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=0001-website-Add-community-page.patch =46rom fe6910a5877ad039e2d6cf95efc10a62c0762871 Mon Sep 17 00:00:00 2001 From: Julien Lepiller Date: Fri, 9 Oct 2020 00:32:56 +0200 Subject: [PATCH] website: Add community page. * website/apps/media/templates/community.scm: New file. * website/apps/media/builder.scm: Add community builder. * website/apps/base/templates/components.scm: Add it to the menu. * website/apps/media/templates/components.scm: Add resource->shtml. * website/apps/media/types.scm: New resource data type. * website/apps/media/data.scm: Add community resources. * website/static/base/css/index.css: Add css for new classes. * website/static/media/css/community.css: New file. * website/static/media/img/community/carl-dong-bitcoin-security.webp: New f= ile. --- website/apps/base/templates/components.scm | 3 +- website/apps/media/builder.scm | 16 ++++- website/apps/media/data.scm | 49 ++++++++++++++ website/apps/media/templates/community.scm | 34 ++++++++++ website/apps/media/templates/components.scm | 24 ++++++- website/apps/media/types.scm | 63 +++++++++++++++++- website/static/base/css/index.css | 12 ++++ website/static/media/css/community.css | 13 ++++ .../community/carl-dong-bitcoin-security.webp | Bin 0 -> 13952 bytes 9 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 website/apps/media/templates/community.scm create mode 100644 website/static/media/css/community.css create mode 100644 website/static/media/img/community/carl-dong-bitcoin-se= curity.webp diff --git a/website/apps/base/templates/components.scm b/website/apps/base= /templates/components.scm index 44d410e..7482503 100644 --- a/website/apps/base/templates/components.scm +++ b/website/apps/base/templates/components.scm @@ -413,7 +413,8 @@ manual. #:items (list (C_ "website menu" (menu-item #:label "Videos" #:active-item acti= ve-item #:url (guix-url "videos/"))) - (C_ "website menu" (menu-item #:label "Screenshots" #:active-item= active-item #:url (guix-url "screenshots/"))))) + (C_ "website menu" (menu-item #:label "Screenshots" #:active-item= active-item #:url (guix-url "screenshots/"))) + (C_ "website menu" (menu-item #:label "Community Resources" #:act= ive-item active-item #:url (guix-url "community/"))))) =20 ,(C_ "website menu" (menu-item #:label "Donate" #:active-item active= -item #:url (guix-url "donate/"))) =20 diff --git a/website/apps/media/builder.scm b/website/apps/media/builder.scm index 53378e6..c4cb17b 100644 --- a/website/apps/media/builder.scm +++ b/website/apps/media/builder.scm @@ -1,11 +1,13 @@ ;;; GNU Guix web site ;;; Copyright =C2=A9 2019 Florian Pelz +;;; Copyright =C2=A9 2020 Julien Lepiller ;;; Initially written by sirgazil who waives all ;;; copyright interest on this file. =20 (define-module (apps media builder) #:use-module (apps aux system) #:use-module (apps media data) + #:use-module (apps media templates community) #:use-module (apps media templates screenshot) #:use-module (apps media templates screenshots-overview) #:use-module (apps media templates video) @@ -17,6 +19,7 @@ #:use-module (apps aux web) #:use-module (apps media utils) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-19) #:export (builder)) =20 =20 @@ -41,7 +44,8 @@ A list of page objects that represent the web resources of the application. See Haunt objects for more information." (flatten - (list (screenshots-overview-builder) + (list (community-builder) + (screenshots-overview-builder) (screenshots-builder) (videos-builder) (video-list-builder)))) @@ -51,6 +55,16 @@ ;;; Helper builders. ;;; =20 +(define (community-builder) + "Return a Haunt page representing the community resources page." + (make-page "community/index.html" + (community-t (sort resources + (lambda (a b) + (time>=3D? + (date->time-utc (resource-date a)) + (date->time-utc (resource-date b)))))) + sxml->html)) + (define (screenshots-builder) "Return a list of Haunt pages representing screenshot pages." (map diff --git a/website/apps/media/data.scm b/website/apps/media/data.scm index 76af25d..89f7a8c 100644 --- a/website/apps/media/data.scm +++ b/website/apps/media/data.scm @@ -1,5 +1,6 @@ ;;; GNU Guix web site ;;; Copyright =C2=A9 2019 Florian Pelz +;;; Copyright =C2=A9 2020 Julien Lepiller ;;; Initially written by sirgazil who waives all ;;; copyright interest on this file. =20 @@ -9,6 +10,7 @@ #:use-module (apps media types) #:use-module (srfi srfi-19) #:export (playlists + resources screenshots)) =20 =20 @@ -85,6 +87,53 @@ distribution.")) #:last-updated (string->date "2020-03-28T16:00:00" "~Y-~m-~dT~H:~M:~S= "))))) =20 =20 +(define resources + (list + (resource + #:title (C_ "community resource title" "Everyday use of Guix") + #:link "https://media.marusich.info/everyday-use-of-gnu-guix-chris-m= arusich-seagl-2018.webm" + #:type 'video + #:language (G_ "English") + #:author "Chris Marushich" + #:date (string->date "2018-10-10" "~Y-~m-~d")) + (resource + #:title (C_ "community resource title" "Bitcoin Build System Securit= y") + #:link "https://www.youtube.com/watch?v=3DI2iShmUTEl8" + #:type 'video + #:language (G_ "English") + #:preview (guix-url "static/media/img/community/carl-dong-bitcoin-se= curity.webp") + #:author "Carl Dong" + #:date (string->date "2019-06-08" "~Y-~m-~d")) + (resource + #:title (C_ "community resource title" "Reproducible System Administ= ration with GNU Guix") + #:link "https://replay.jres.org/videos/watch/c77b3a44-b75f-4c10-9f39= -8fb55ae096d7" + #:type 'video + #:language (G_ "French") + #:author "Julien Lepiller" + #:date (string->date "2019-12-04" "~Y-~m-~d")) + (resource + #:title (C_ "community resource title" "Au-del=C3=A0 des conteneurs = : environnements logiciels reproductibles avec GNU Guix") + #:link "https://webcast.in2p3.fr/video/au-dela-des-conteneurs-enviro= nnements-logiciels-reproductibles-avec-gnu-guix-1" + #:type 'video + #:language (G_ "French") + #:author "Ludovic Court=C3=A8s" + #:date (string->date "2019-05-23" "~Y-~m-~d")) + (resource + #:title (C_ "community resource title" "Code Staging in GNU Guix") + #:link "https://arxiv.org/abs/1709.00833" + #:type 'article + #:language (G_ "English") + #:author "Ludovic Court=C3=A8s" + #:date (string->date "2017-09-04" "~Y-~m-~d")) + (resource + #:title (C_ "community resource title" "Guix: A most advanced operat= ing system") + #:link "https://ambrevar.xyz/guix-advance/index.html" + #:type 'blog + #:language (G_ "English") + #:author "Pierre Neidhardt" + #:date (string->date "2019-01-14" "~Y-~m-~d")))) + + (define screenshots (list (screenshot diff --git a/website/apps/media/templates/community.scm b/website/apps/medi= a/templates/community.scm new file mode 100644 index 0000000..6cd51a0 --- /dev/null +++ b/website/apps/media/templates/community.scm @@ -0,0 +1,34 @@ +;;; GNU Guix web site +;;; Copyright =C2=A9 2020 Julien Lepiller +;;; Initially written by sirgazil who waives all +;;; copyright interest on this file. + +(define-module (apps media templates community) + #:use-module (apps base templates theme) + #:use-module (apps base utils) + #:use-module (apps i18n) + #:use-module (apps media templates components) + #:export (community-t)) + +(define (community-t community-resources) + "Return an SHTML page for all COMMUNITY-RESOURCES." + (theme + #:title (C_ "webpage title" '("Community")) + #:description (G_ "Links to resources created by the community") + #:keywords + (string-split ;TRANSLATORS: |-separated list of webpage keywords + (G_ "GNU|Linux|Unix|Free software|Libre software|Operating \ +system|GNU Hurd|GNU Guix package manager|GNU Guile|Guile \ +Scheme|Transactional upgrades|Functional package \ +management|Reproducibility") #\|) + #:active-menu-item (C_ "website menu" "Media") + #:css (list (guix-url "static/base/css/index.css") + (guix-url "static/base/css/item-preview.css") + (guix-url "static/media/css/community.css")) + #:content + `(main + (section + (@ (class "page")) + (div + (@ (class "resource-box")) + ,@(map resource->shtml community-resources)))))) diff --git a/website/apps/media/templates/components.scm b/website/apps/med= ia/templates/components.scm index d928d23..85574ee 100644 --- a/website/apps/media/templates/components.scm +++ b/website/apps/media/templates/components.scm @@ -1,5 +1,6 @@ ;;; GNU Guix web site ;;; Copyright =C2=A9 2019 Florian Pelz +;;; Copyright =C2=A9 2020 Julien Lepiller ;;; Initially written by sirgazil who waives all ;;; copyright interest on this file. =20 @@ -14,7 +15,8 @@ #:use-module (apps media types) #:use-module (apps media utils) #:use-module (srfi srfi-19) - #:export (screenshot->shtml + #:export (resource->shtml + screenshot->shtml screenshots-box video->shtml video-content @@ -25,6 +27,26 @@ ;;; Components. ;;; =20 +(define (resource->shtml resource) + `(a + (@ (class "community-preview item-preview") + (href ,(resource-link resource))) + (div + (@ (class "community-image")) + (div + (img + (@ (class "responsive-image") + (src ,(or (resource-preview resource) + (case (resource-type resource) + ((video) (guix-url "static/base/img/videos-icon.png"= )) + ((article blog) (guix-url "static/base/img/manual-ic= on.png"))))) + (alt ""))))) + (h3 ,(resource-title resource)) + (p + ,(G_ `(" published " ,(date->string (resource-date resource) "~b ~d, = ~Y") + " by " ,(resource-author resource) + " in " ,(resource-language resource)))))) + (define (screenshot->shtml shot) "Return an SHTML representation of the given screenshot object. =20 diff --git a/website/apps/media/types.scm b/website/apps/media/types.scm index 50c0989..ab54af8 100644 --- a/website/apps/media/types.scm +++ b/website/apps/media/types.scm @@ -5,7 +5,16 @@ =20 (define-module (apps media types) #:use-module (srfi srfi-9) - #:export (screenshot + #:export (resource + resource? + resource-author + resource-date + resource-language + resource-link + resource-preview + resource-title + resource-type + screenshot screenshot? screenshot-caption screenshot-image @@ -32,6 +41,58 @@ ;;; Data types. ;;; =20 +;;; Resource (record type) +;;; ---------------------- +;;; +;;; A community resource object represents a link to a resource created ou= tside +;;; of the Guix project, that talks about Guix. +;;; +;;; Objects of this type can be created with the "resource" precodure (see +;;; Helper procedures below). +;;; +;;; Fields: +;;; +;;; title (string) +;;; The title of the resource +;;; +;;; link (string) +;;; The link to the resource +;;; +;;; author (string) +;;; The name of the author +;;; +;;; date (date) +;;; The date of publication +;;; +;;; preview (string) +;;; A URL to a small size image that represents the resource, or `#f' if +;;; it cannot be represented by an image. +;;; +;;; language (string) +;;; The name of the language in which the resource is written or spoken. +;;; +;;; type (symbol) +;;; The type of the resource, which can be one of: +;;; - 'article: a scientific or journalistic publication +;;; - 'blog: a blog post +;;; - 'video: a video presentation +(define-record-type + (make-resource title link author date preview language type) + resource? + (title resource-title) + (link resource-link) + (author resource-author) + (date resource-date) + (preview resource-preview) + (language resource-language) + (type resource-type)) + +;;; Helper procedures. + +(define* (resource #:key title link author date preview language type) + "Return a object with the given attributes." + (make-resource title link author date preview language type)) + ;;; Screenshot (record type) ;;; ------------------------ ;;; diff --git a/website/static/base/css/index.css b/website/static/base/css/in= dex.css index ea52a6d..707091b 100644 --- a/website/static/base/css/index.css +++ b/website/static/base/css/index.css @@ -66,6 +66,18 @@ h3 { color: #E6E6E6; } =20 +.resource-box { + padding: 40px 10px 0px 10px; + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.community-preview { + max-width: 270px; + padding: 0.5em; +} + .screenshots-box { padding: 40px 0px 0px 0px; } diff --git a/website/static/media/css/community.css b/website/static/media/= css/community.css new file mode 100644 index 0000000..54de8d7 --- /dev/null +++ b/website/static/media/css/community.css @@ -0,0 +1,13 @@ +.community-image { + width: 180px; + height: 180px; + display: flex; + margin: auto; + flex-direction: row; + align-items: center; +} + +.community-image img { + max-width: 180px; + max-height: 180px; +} diff --git a/website/static/media/img/community/carl-dong-bitcoin-security.= webp b/website/static/media/img/community/carl-dong-bitcoin-security.webp new file mode 100644 index 0000000000000000000000000000000000000000..017c00dd5c4b76614102b50a6bd= b2f6887145a07 GIT binary patch literal 13952 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