From c70da2eaac617e854ca015e578658c922e477ab4 Mon Sep 17 00:00:00 2001 From: Drew Date: Fri, 25 Apr 2025 23:30:12 -0600 Subject: [PATCH] initial template --- .gitlab-ci.yml | 65 +++++++++++++++++++++ README.md | 80 ++++++++++++++++++++++++++ archetypes/default.md | 5 ++ assets/css/styles.css | 2 + assets/js/script.js | 1 + hugo.toml | 7 +++ layouts/_default/baseof.html | 77 +++++++++++++++++++++++++ layouts/_default/section.html | 12 ++++ layouts/_default/single.html | 9 +++ layouts/_default/taxonomy.html | 26 +++++++++ layouts/partials/footer.html | 6 ++ layouts/partials/header.html | 25 ++++++++ layouts/partials/image.html | 19 ++++++ layouts/partials/related-articles.html | 40 +++++++++++++ layouts/partials/taxonomy-cloud.html | 10 ++++ 15 files changed, 384 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 README.md create mode 100644 archetypes/default.md create mode 100644 assets/css/styles.css create mode 100644 assets/js/script.js create mode 100644 hugo.toml create mode 100644 layouts/_default/baseof.html create mode 100644 layouts/_default/section.html create mode 100644 layouts/_default/single.html create mode 100644 layouts/_default/taxonomy.html create mode 100644 layouts/partials/footer.html create mode 100644 layouts/partials/header.html create mode 100644 layouts/partials/image.html create mode 100644 layouts/partials/related-articles.html create mode 100644 layouts/partials/taxonomy-cloud.html diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..42dd4a9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,65 @@ +# Default image for jobs - contains Hugo Extended +image: + name: hugomods/hugo:node + entrypoint: [""] + +variables: + HUGO_ENV: production + # Tells GitLab Runner to initialize and update submodules recursively + GIT_SUBMODULE_STRATEGY: recursive + # TODO: the Surfer server base url (ex: "https://www.example.com/") + SURFER_SERVER: "" + +stages: + - build # Added build stage + - deploy + +# Job to build the Hugo site +build_site: + stage: build + before_script: + - echo "installing NPM packages" + - npm install + script: + - echo "Starting Hugo build..." + - hugo version + - hugo --minify --gc --cleanDestinationDir # Build the site + - echo "Build completed. Public directory contents:" + - ls -la public/ + artifacts: + paths: + - public/ # Pass the 'public' directory to the next stage + expire_in: 1 hour # Optional: Set artifact expiry + # Define when this job runs (e.g., only on the main branch) + # Adjust 'only' or 'rules' as needed for your workflow + only: + - publish # the script will only run on the branch 'publish' + +# Job to deploy the built site using cloudron-surfer +deploy_site: + stage: deploy + image: node:18 # Use Node.js image for cloudron-surfer + needs: # Ensure 'build_site' job completes successfully first + - job: build_site + artifacts: true # Download artifacts from 'build_site' + variables: + GIT_STRATEGY: none # Optimization: Don't fetch repo source code for deploy job + before_script: + - echo "Installing cloudron-surfer..." + - npm install -g cloudron-surfer + script: + - 'echo "Deploying to: $SURFER_SERVER"' + # Verify artifact downloaded correctly + - echo "Contents of downloaded artifact:" + - ls -la public/ # Artifacts are extracted to the root of the job workspace + - echo "Uploading files to server using surfer put..." + # TODO: Makesure to add a $SURFER_TOKEN to GitLab under the repo settings > CI/CD > Variables + - >- + surfer put + --token $SURFER_TOKEN + --server $SURFER_SERVER + public/* / + - echo "Deployment completed successfully" + only: + - publish # Example: Run only on the main branch + diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a35e08 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# MedLab Hugo Base Theme + +This is the base theme for MedLab Hugo projects. This theme provides a starting point for creating websites using Hugo, a powerful static site generator. + +## Table of Contents +- [Getting Started](#getting-started) +- [Development](#development) +- [Content Management](#content-management) +- [GitLab CI/CD](#gitlab-cicd) + +## Getting Started + +## Development + +1. Install Hugo: Follow the instructions on the [Hugo website](https://gohugo.io/getting-started/installing/) to install Hugo on your machine. +2. Clone the repository: Clone this repository to your local machine using Git. +3. Navigate to the project directory: Open a terminal and navigate to the directory where you cloned the repository. +4. Start the Hugo server: Run the following command to start the Hugo server: + ```bash + hugo server + ``` +5. Open your web browser: Open your web browser and go to `http://localhost:1313` to view the website. + +## Content Management + +1. Add content: Create new Markdown files in the `content` directory to add content to your website. You can create subdirectories to organize your content. +2. Front matter: Each Markdown file should have front matter at the top of the file. The front matter is a YAML block that contains metadata about the page, such as the title, date, and layout. Here is an example of front matter: + ```yaml + --- + title: "My Page Title" + date: 2023-10-01 + layout: "single" + --- + ``` +3. Markdown syntax: Use Markdown syntax to format your content. You can use headings, lists, links, images, and other Markdown features to create your content. For more information on Markdown syntax, see the [Markdown documentation](https://www.markdownguide.org/basic-syntax/). + +## GitLab CI/CD + +This project includes automated CI/CD pipelines that handle building and deploying your Hugo site. The pipeline automatically builds your site when changes are pushed and deploys it to a Surfer instance. + +### Pipeline Overview +- **Build Stage**: Compiles Hugo site with optimizations +- **Deploy Stage**: Deploys to Surfer using cloudron-surfer + +### Setting up the pipeline + +1. **Create GitLab Project** + - For external repositories (like git.medlab.host): + - Use GitLab's "Run CI/CD for external repo" option + - This creates a mirrored GitLab project + +2. **Configure Repository Mirroring** (for external hosting) + - Navigate to: `Settings > Repository > Mirror Settings` + - Add your GitLab repository URL + - Enable push mirroring + +3. **Set Required Variables** + - Go to: `Settings > CI/CD > Variables` + - Add these variables: + - `SURFER_TOKEN`: Your Surfer access token + - Mark as "Masked and hidden" + - In the `.gitlab-ci.yml` file, set the following variable: + - `SURFER_SERVER`: Your Surfer server URL + - Example: "https://www.example.com/" + - If you don't want to be visible to the public you can set this variable in GitLab CI/CD settings as well. + +4. **Deployment Process** + - Push changes to the `publish` branch to trigger deployment + - Pipeline will: + 1. Build Hugo site (with minification) + 2. Deploy to Surfer + - Monitor progress in GitLab's CI/CD Pipeline view + +### Important Notes +- Ensure `.gitlab-ci.yml` exists in your repository root +- The pipeline uses `hugomods/hugo:node` for Hugo Extended support +- Deployments only trigger on the `publish` branch +- Build artifacts are retained for 1 hour + +For more details about Surfer deployment, see: https://docs.cloudron.io/apps/surfer/ diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..25b6752 --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +date = '{{ .Date }}' +draft = true +title = '{{ replace .File.ContentBaseName "-" " " | title }}' ++++ diff --git a/assets/css/styles.css b/assets/css/styles.css new file mode 100644 index 0000000..fea6133 --- /dev/null +++ b/assets/css/styles.css @@ -0,0 +1,2 @@ +/* This is the main css file, you can import other files to keep things tidy, or just go wild and put it all in here! */ +/* @import "components/thingy.css"; */ diff --git a/assets/js/script.js b/assets/js/script.js new file mode 100644 index 0000000..f963f86 --- /dev/null +++ b/assets/js/script.js @@ -0,0 +1 @@ +// add your javascript here, all javscript code in /assets/js/ will be bundled \ No newline at end of file diff --git a/hugo.toml b/hugo.toml new file mode 100644 index 0000000..ee5c697 --- /dev/null +++ b/hugo.toml @@ -0,0 +1,7 @@ +baseURL = 'https://example.org/' +languageCode = 'en-us' +title = 'My New Medlab Hugo Site' + +[params] + description = "The Medlab Hugo theme is a basic starter theme for Hugo." + openGraphImage = "/images/og-default.jpg" \ No newline at end of file diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html new file mode 100644 index 0000000..f6fdbc2 --- /dev/null +++ b/layouts/_default/baseof.html @@ -0,0 +1,77 @@ + + + + + + + {{/* Generate consistent title */}} + {{ $title := "" }} + {{ if if .IsHome }} + {{ $title = .Title }} + {{ else }} + {{ $title = printf "%s - %s" .Title .Site.Title }} + {{ end }} + + + {{ $title }} + + {{/* Generate description from summary, description, or default site description */}} + {{ $description := "" }} + {{ with .Description }} + {{ $description = . }} + {{ else }} + {{ $description = .Site.Params.description }} + {{ end }} + + + {{/* Generate keywords from topics */}} + {{ with .Params.topics }} + + {{ end }} + + + + + + + + {{ with .Params.ogImage | default .Site.Params.openGraphImage }} + + {{ end }} + + + + + + {{ with .Params.ogImage | default .Site.Params.openGraphImage }} + + {{ end }} + + + + + + {{ $style := resources.Get "css/styles.css" }} + {{ if hugo.IsProduction }} + {{ $style = $style | minify | fingerprint }} + + {{ else }} + + {{ end }} + + + {{ partial "header.html" . }} + + {{ block "main" . }}{{ end }} + + {{ partial "footer.html" . }} + + {{ $js := resources.Match "js/*.js" | resources.Concat "js/bundle.js" }} + {{ if hugo.IsProduction }} + {{ $js = $js | minify | fingerprint }} + + {{ else }} + + {{ end }} + + diff --git a/layouts/_default/section.html b/layouts/_default/section.html new file mode 100644 index 0000000..47e0c7a --- /dev/null +++ b/layouts/_default/section.html @@ -0,0 +1,12 @@ +{{ define "main" }} +

{{ .Title }}

+ +{{ end }} \ No newline at end of file diff --git a/layouts/_default/single.html b/layouts/_default/single.html new file mode 100644 index 0000000..abc0351 --- /dev/null +++ b/layouts/_default/single.html @@ -0,0 +1,9 @@ +{{ define "main" }} +
+ +

{{ .Title }}

+ + {{ .Content }} + +
+{{ end }} \ No newline at end of file diff --git a/layouts/_default/taxonomy.html b/layouts/_default/taxonomy.html new file mode 100644 index 0000000..c18f2d4 --- /dev/null +++ b/layouts/_default/taxonomy.html @@ -0,0 +1,26 @@ +{{ define "main" }} +
+

{{ .Data.Singular }}

+

{{ .Title }}

+
+
+ + + {{ if gt (len (index .Site.Taxonomies .Data.Singular)) 1 }} +
+

Other {{ .Data.Plural }}

+
+ {{ partial "taxonomy-cloud" (dict "taxonomy" .Data.Singular "Site" .Site "page" .Page) }} +
+
+ {{ end }} +
+{{ end }} \ No newline at end of file diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html new file mode 100644 index 0000000..59d5f29 --- /dev/null +++ b/layouts/partials/footer.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/layouts/partials/header.html b/layouts/partials/header.html new file mode 100644 index 0000000..a5fab07 --- /dev/null +++ b/layouts/partials/header.html @@ -0,0 +1,25 @@ + +
+
+

+ {{ .Site.Title }} +

+ +
+
+
+
+
+
diff --git a/layouts/partials/image.html b/layouts/partials/image.html new file mode 100644 index 0000000..a64500a --- /dev/null +++ b/layouts/partials/image.html @@ -0,0 +1,19 @@ +{{ $width := .width }} +{{ $height := default $width .height }} +{{ $class := .class }} +{{ $resource := .resource }} +{{ $alt := .alt }} + +{{ with $resource }} + {{ $image := .Fit (printf "%dx%d webp" (int $width) (int $height)) }} + {{ $fallback := .Fit (printf "%dx%d" (int $width) (int $height)) }} + + + {{ $alt }} + +{{ end }} diff --git a/layouts/partials/related-articles.html b/layouts/partials/related-articles.html new file mode 100644 index 0000000..9ff1ae3 --- /dev/null +++ b/layouts/partials/related-articles.html @@ -0,0 +1,40 @@ +{{- $topics := .topics -}} +{{- $limit := default 3 .limit -}} +{{- $currentPath := .page.RelPermalink -}} + +{{- $related := where (where site.RegularPages "Type" "articles") "RelPermalink" "!=" $currentPath -}} +{{- $matchingArticles := slice -}} + +{{/* First try to find articles with matching topics */}} +{{- range $related -}} + {{- $matches := 0 -}} + {{- range .Params.topics -}} + {{- if in $topics . -}} + {{- $matches = add $matches 1 -}} + {{- end -}} + {{- end -}} + {{- if gt $matches 0 -}} + {{- $matchingArticles = $matchingArticles | append (dict "page" . "matches" $matches) -}} + {{- end -}} +{{- end -}} + +{{/* If we found matching articles, sort by number of matching topics */}} +{{- $finalArticles := slice -}} +{{- if gt (len $matchingArticles) 0 -}} + {{- $finalArticles = first $limit (sort $matchingArticles "matches" "desc") -}} +{{- else -}} + {{/* Fallback to showing other articles sorted by date */}} + {{- $finalArticles = first $limit (sort $related "Date" "desc") -}} +{{- end -}} + +{{- if gt (len $finalArticles) 0 -}} + +{{- end -}} diff --git a/layouts/partials/taxonomy-cloud.html b/layouts/partials/taxonomy-cloud.html new file mode 100644 index 0000000..919a6c9 --- /dev/null +++ b/layouts/partials/taxonomy-cloud.html @@ -0,0 +1,10 @@ +{{ $taxonomy := .taxonomy }} +{{ range $term, $pages := index .Site.Taxonomies $taxonomy }} +{{ $termPage := $.Site.GetPage (printf "/%s/%s" $taxonomy $term) }} + + {{ $term }} + +{{ end }}