Skip to content

Commit 2bc21f8

Browse files
committed
Overhaul the site with validation and AGENTS.md
* Add HTML validation and AGENTS.md to the site. * Fix the current issues with HTML valiation. * Use the standard compose.yml filename for Docker.
1 parent 83a112d commit 2bc21f8

File tree

13 files changed

+356
-4
lines changed

13 files changed

+356
-4
lines changed

AGENTS.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# AGENTS.md
2+
3+
This file tells automation agents how to build, test, lint and deploy this
4+
project.
5+
6+
## Style Instructions
7+
8+
9+
## Development
10+
11+
Set up the project with the templates for development site like so:
12+
13+
```sh
14+
git submodule update --init
15+
```
16+
17+
You can run Hugo to build the HTML and other content for the site to test
18+
changes like so:
19+
20+
```
21+
docker compose run --remove-orphans site hugo
22+
```
23+
24+
With Docker compose running validate pages rendered with the HTML validator for
25+
quality like so (reads files from the public directory):
26+
27+
```
28+
./validate-page.sh content/blog/post/example-filename.md
29+
```
30+
31+
## Formatting Instructions
32+
33+
When writing Markdown files, try to keep the contents of Markdown files inside
34+
of an 80 character limit unless if shortening the line would break formatting,
35+
such as for hyperlinks with long URLs.
36+
37+
When writing blog posts, pay close attention to the TOML data at the top of
38+
files and try not to invent new keys. Use only what you've seen before in the
39+
repository. For example:
40+
41+
```
42+
---
43+
type: post
44+
title: An Article Title
45+
author: Andrew Wray
46+
subtitle: A subtitle for an article
47+
date: 1970-01-01
48+
summary: A short summary for an article
49+
tags: ["example-tag-1", "example-tag-2"]
50+
---
51+
```
52+
53+
For `date` be sure to write in today's date in ISO-8601 format. For `title` be
54+
sure to write titles in Associated Press style titlecase format.

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# denseanalyis.org
1+
# denseanalysis.org
22

33
The Dense Analysis website built with [Hugo](https://gohugo.io/) to generate the
44
entire site as static content. The site is served as static content to keep
55
maintenance costs low, to improve performance, and to increase security.
66

7-
This project uses an AGPL licence to ensure that it will always be available for
7+
This project uses an AGPL license to ensure that it will always be available for
88
those who need it.
99

1010
## Development
@@ -18,11 +18,20 @@ git submodule update --init
1818
docker compose up
1919
```
2020

21+
The site will immediately start and you can view it at http://localhost:1313
22+
23+
You can validate pages via the `./validate-path.sh` script by passing in a path
24+
to a page or a file path in the `content/` directory.
25+
2126
The site will be built into the `public` directory, which can be served via
2227
nginx or Apache. See the rest of the
2328
[Hugo documentation](https://gohugo.io/documentation/)
2429
for knowledge on how to build sites with Hugo.
2530

31+
You can validate pages via the `./validate-path.sh` script by passing in a path
32+
to a page or a file path in the `content/` directory. Files will be pulled in
33+
from the `public` directory for validation.
34+
2635
## Deployment
2736

2837
Just run `./deploy.sh` on a server, which is what GitHub actions will execute on

docker-compose.yml renamed to compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
services:
44
site:
5+
container_name: '${COMPOSE_PROJECT_NAME}-site'
56
image: hugomods/hugo:reg-0.126.0
67
ports:
78
- "1313:1313"
@@ -11,5 +12,6 @@ services:
1112
- ./static:/workdir/static
1213
- ./themes:/workdir/themes
1314
- ./config.toml:/workdir/config.toml
15+
- ./public:/workdir/public
1416
working_dir: /workdir
1517
command: hugo serve --bind 0.0.0.0

content/about/foss.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ loses relevance to the general public, any capable person can take the source
2727
code and modify it to function as they see fit, and the software can be
2828
maintained in this manner _in perpetuity_.
2929

30-
---
30+
## Further Reading
3131

3232
We recommend as further reading the GNU Project's page ["What is Free
3333
Software."](https://www.gnu.org/philosophy/free-sw.html)

content/blog/post/2025-03-27-openapi-spec-converter.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Hub](https://hub.docker.com/r/denseanalysis/openapi-spec-converter),
1818
`openapi-spec-converter` makes it easy for developers to standardize and migrate
1919
their API specifications with minimal effort.
2020

21+
## Instructions
22+
2123
With a simple command, users can convert their JSON and YAML-based
2224
specifications:
2325

@@ -32,6 +34,8 @@ supporting conversions to **Swagger (`swagger`)**, **OpenAPI 3.0 (`3.0`)**, and
3234
YAML or JSON output can be specified by setting `-f yaml` or `-f json`. By
3335
default the converter will output JSON.
3436

37+
## Contributing
38+
3539
`openapi-spec-converter` is part of Dense Analysis’s commitment to improving
3640
developer workflows and fostering inter-operability in API development.
3741

content/services/community.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Community
33
subtitle: Community events and more!
44
---
55

6+
## Public Events
7+
68
Dense Analysis is run by qualified engineers with experience in running
79
developer "hackathons," public events, and much more. We are especially
810
interested in running events for promoting free software, and for showcasing and

content/services/speaking.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Speaking
33
subtitle: Hear from qualified experts
44
---
55

6+
## Public Speaking
7+
68
Do you need someone to speak at a conference about free software? Are you
79
looking for someone to speak at a local event? Dense Analysis is run by
810
qualified engineers with experience in public speaking. We are especially

content/sponsors.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ We offer the following sponsorship benefits.
1414
* **Silver Sponsors** cans have their names featured below.
1515
* **Gold Sponsors** can have their logos featured on this page.
1616

17-
---
17+
## Current Sponsors
18+
19+
_There is no one here! You could be the first!_
1820

1921
_This page will be updated monthly._

layouts/partials/head.html

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{{- if eq .Kind "taxonomyTerm" }}
2+
{{- range $key, $value := .Data.Terms.ByCount }}
3+
{{- $.Scratch.Add "most_used" (slice $value.Name) }}
4+
{{- end }}
5+
{{- if not ($.Scratch.Get "most_used") }}
6+
{{- $description := printf "A full overview of all pages with %s, ordered by %s" .Data.Plural .Data.Singular | truncate 180 }}
7+
{{- $.Scratch.Set "Description" $description }}
8+
{{- else }}
9+
{{- $description := printf "A full overview of all pages with %s, ordered by %s, such as: %s" .Data.Plural .Data.Singular ( delimit ( $.Scratch.Get "most_used" ) ", " ", and " ) | truncate 180 }}
10+
{{- $.Scratch.Set "Description" $description }}
11+
{{- end }}
12+
13+
{{- $title := printf "Overview of all pages with %s, ordered by %s" .Data.Plural .Data.Singular }}
14+
{{- $.Scratch.Set "Title" $title }}
15+
{{- else if eq .Kind "taxonomy" }}
16+
{{- $description := printf "Overview of all pages with the %s #%s, such as: %s" .Data.Singular $.Title ( index .Pages 0).Title | truncate 160 }}
17+
{{- $.Scratch.Set "Description" $description }}
18+
19+
{{- $title := printf "Overview of all pages with the %s #%s" .Data.Singular $.Title }}
20+
{{- $.Scratch.Set "Title" $title }}
21+
{{- else }}
22+
{{- $.Scratch.Set "Description" ( .Description | default .Params.subtitle | default .Summary ) }}
23+
{{- $.Scratch.Set "Title" ( .Title | default .Site.Title ) }}
24+
{{- end }}
25+
26+
<meta charset="utf-8">
27+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
28+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes">
29+
30+
<!-- Site Title, Description, Author, and Favicon -->
31+
32+
{{ if .IsHome }}
33+
{{- with .Site.Params.homeTitle }}
34+
<title>{{ . }}</title>
35+
{{- end }}
36+
{{ else }}
37+
{{- with ($.Scratch.Get "Title") }}
38+
<title>{{ . }} - {{ $.Site.Params.homeTitle }}</title>
39+
{{- end }}
40+
{{ end }}
41+
42+
{{- with ($.Scratch.Get "Description") }}
43+
<meta name="description" content="{{ . }}">
44+
{{- end }}
45+
{{- with .Site.Author.name }}
46+
<meta name="author" content="{{ . }}"/>
47+
{{- end }}
48+
{{- partial "seo/main.html" . }}
49+
{{- with .Site.Params.favicon }}
50+
<link href='{{ . | absURL }}' rel='icon' type='image/x-icon'>
51+
{{- end -}}
52+
<!-- Hugo Version number -->
53+
{{ hugo.Generator -}}
54+
<!-- Links and stylesheets -->
55+
<link rel="alternate" href="{{ "index.xml" | absLangURL }}" type="application/rss+xml" title="{{ .Site.Title }}">
56+
57+
{{- if .Site.Params.selfHosted -}}
58+
<link rel="stylesheet" href="{{ "css/katex.min.css" | absURL }}">
59+
<link rel="stylesheet" href="{{ "fontawesome/css/all.css" | absURL }}">
60+
<link rel="stylesheet" href="{{ "css/bootstrap.min.css" | absURL }}">
61+
{{- else -}}
62+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
63+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
64+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
65+
{{- end -}}
66+
67+
<link rel="stylesheet" href="{{ "css/main.css" | absURL }}">
68+
69+
{{- if .Site.Params.staticman -}}
70+
<link rel="stylesheet" href="{{ "css/staticman.css" | absURL }}">
71+
{{- end -}}
72+
73+
{{- if .Site.Params.selfHosted -}}
74+
<link rel="stylesheet" href="{{ "css/fonts.css" | absURL }}">
75+
{{- else -}}
76+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic">
77+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800">
78+
{{- end -}}
79+
80+
{{- if .Site.Params.useHLJS }}
81+
<link rel="stylesheet" href="{{ "css/highlight.min.css" | absURL }}">
82+
{{- else -}}
83+
<link rel="stylesheet" href="{{ "css/syntax.css" | absURL }}">
84+
{{- end -}}
85+
<link rel="stylesheet" href="{{ "css/codeblock.css" | absURL }}">
86+
87+
{{- if .Site.Params.staticman.recaptcha -}}
88+
<script src='https://www.google.com/recaptcha/api.js'></script>
89+
{{- end -}}
90+
91+
{{- if .Site.Params.selfHosted -}}
92+
<link rel="stylesheet" href="{{ "css/photoswipe.min.css" | absURL }}">
93+
<link rel="stylesheet" href="{{ "css/photoswipe.default-skin.min.css" | absURL }}">
94+
{{- else -}}
95+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/photoswipe.min.css" integrity="sha384-h/L2W9KefUClHWaty3SLE5F/qvc4djlyR4qY3NUV5HGQBBW7stbcfff1+I/vmsHh" crossorigin="anonymous">
96+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.2/default-skin/default-skin.min.css" integrity="sha384-iD0dNku6PYSIQLyfTOpB06F2KCZJAKLOThS5HRe8b3ibhdEQ6eKsFf/EeFxdOt5R" crossorigin="anonymous">
97+
{{- end -}}
98+
99+
{{- partial "head_custom.html" . }}
100+
{{- if not .Site.IsServer -}}
101+
{{ template "_internal/google_analytics.html" . }}
102+
{{- end -}}

layouts/partials/nav.html

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<nav class="navbar navbar-default navbar-fixed-top navbar-custom">
2+
<div class="container-fluid">
3+
<div class="navbar-header">
4+
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-navbar">
5+
<span class="sr-only">{{ i18n "toggleNavigation" }}</span>
6+
<span class="icon-bar"></span>
7+
<span class="icon-bar"></span>
8+
<span class="icon-bar"></span>
9+
</button>
10+
<a class="navbar-brand" href="{{ "" | absLangURL }}">{{ .Site.Title }}</a>
11+
</div>
12+
13+
<div class="collapse navbar-collapse" id="main-navbar">
14+
<ul class="nav navbar-nav navbar-right">
15+
{{ range .Site.Menus.main.ByWeight }}
16+
{{ if .HasChildren }}
17+
<li class="navlinks-container">
18+
<a class="navlinks-parent">{{ .Name }}</a>
19+
<div class="navlinks-children">
20+
{{ range .Children }}
21+
<a href="{{ .URL | relLangURL }}">{{ .Name }}</a>
22+
{{ end }}
23+
</div>
24+
</li>
25+
{{ else }}
26+
<li>
27+
<a title="{{ .Name }}" href="{{ .URL | relLangURL }}">{{ .Name }}</a>
28+
</li>
29+
{{ end }}
30+
{{ end }}
31+
32+
{{ if .Site.IsMultiLingual }}
33+
{{ if ge (len .Site.Languages) 3 }}
34+
<li class="navlinks-container">
35+
<a class="navlinks-parent">{{ i18n "languageSwitcherLabel" }}</a>
36+
<div class="navlinks-children">
37+
{{ range .Site.Languages }}
38+
{{ if not (eq .Lang $.Site.Language.Lang) }}
39+
<a href="/{{ .Lang }}" lang="{{ .Lang }}">{{ default .Lang .LanguageName }}</a>
40+
{{ end }}
41+
{{ end }}
42+
</div>
43+
</li>
44+
{{ else }}
45+
<li>
46+
{{ range .Site.Languages }}
47+
{{ if not (eq .Lang $.Site.Language.Lang) }}
48+
<a href="/{{ .Lang }}" lang="{{ .Lang }}">{{ default .Lang .LanguageName }}</a>
49+
{{ end }}
50+
{{ end }}
51+
</li>
52+
{{ end }}
53+
{{ end }}
54+
55+
{{ if isset .Site.Params "gcse" }}
56+
<li>
57+
<a href="#modalSearch" data-toggle="modal" data-target="#modalSearch" style="outline: none;">
58+
<span class="hidden-sm hidden-md hidden-lg">{{ i18n "gcseLabelShort" }}</span> <span id="searchGlyph" class="glyphicon glyphicon-search"></span>
59+
</a>
60+
</li>
61+
{{ end }}
62+
</ul>
63+
</div>
64+
65+
{{ if isset .Site.Params "logo" }}
66+
<div class="avatar-container">
67+
<div class="avatar-img-border">
68+
<a title="{{ .Site.Title }}" href="{{ "" | absLangURL }}">
69+
<img class="avatar-img" src="{{ .Site.Params.logo | absURL }}" alt="{{ .Site.Title }}">
70+
</a>
71+
</div>
72+
</div>
73+
{{ end }}
74+
75+
</div>
76+
</nav>
77+
78+
<!-- Search Modal -->
79+
{{ if isset .Site.Params "gcse" }}
80+
<div id="modalSearch" class="modal fade" role="dialog">
81+
<div class="modal-dialog">
82+
<div class="modal-content">
83+
<div class="modal-header">
84+
<button type="button" class="close" data-dismiss="modal">&times;</button>
85+
<h4 class="modal-title">{{ i18n "gcseLabelLong" . }}</h4>
86+
</div>
87+
<div class="modal-body">
88+
<gcse:search></gcse:search>
89+
</div>
90+
<div class="modal-footer">
91+
<button type="button" class="btn btn-default" data-dismiss="modal">{{ i18n "gcseClose" }}</button>
92+
</div>
93+
</div>
94+
</div>
95+
</div>
96+
{{ end }}

0 commit comments

Comments
 (0)