Skip to content

seabilwe/QGIS-Hugo

 
 

Repository files navigation

QGIS Hugo Website

Screenshot

By Tim Sutton and QGIS Contributors.

Project Status

E2E Tests Deploy Hugo site to Pages Website Status License

Project stars: Stars

🏃‍♀️Before you start

This web site is a static site built using Hugo.

Hugo Logo

If you want to understand Hugo and the other technologies we used to build this site, there is some recommended reading for you below:

  • Read this article on templates if you are looking to understand how templates work.

  • Read this article on hugo pipes, minifying content etc.

  • Read this article to see how you can use Hugo variables in your SCSS.

  • Read this article to see the general process of customizing bulma with SASS. Note that in addition to this workflow, we also generate our SASS primary file (bulma.sass) from a Hugo template.

  • This theme uses the Bulma CSS framework, which you should familiarise yourself with if you want to change the theme.

  • View the website design QGIS website figma

  • The relationship between some of the key concepts in Hugo is shown below: Overview diagram

The following key skills are needed for theme developers (DEV) and content creators (CC):

Technology Notes Who?
Markdown Essential skill for content creators. DEV / CC
VSCode Streamlines your workflow. You can work directly in the GitHub website too. DEV / CC
----------- -------- -------
HTML Needed for creating templates (shortcodes & partials). DEV
CSS Note that we also use Bulma. DEV
Javascript We are trying to use as little javascript as possible. DEV
Python A few utility scripts only. Mostly not needed. DEV
SASS Customising Bulma mainly. DEV
GO Mainly Go templating via HUGO. DEV
Bash A few utility scripts only. DEV

Hugo Terminology Glossary

Term Description
content Top level folder for your user created web site content
section Any subfolder of content containing an _index.md file. e.g. the section content/about/ would have within it a file called content/about/_index.md making it a section and resolvable at the URL https://your domain/about/.
nested section As above, creating a subsection, for example content/about/staff/_index.md. Note that if the subsection contains only a single page, it will will be navigable as a page at e.g. https://your domain/about/staff/
section template By default a section with nested subfolders of content will render as a list. If you want to customize the section (i.e. not render as a list) you can make a section template in layouts/-section name-/section.html

🏺 Background & Design Philosophy

The QGIS.org web site receives a lot of traffic so our website is designed to be fast, privacy respecting and open source, like the rest of QGIS.

  • 💨 Fast: all pages are statically generated, there is no database, no bulky javascript or CSS frameworks etc.
  • 🔒 Privacy respecting: as much as possible we avoid things that can be used to track you - no resources loaded from other web sites, no cookies, no trackers, no sessions etc.
  • 🖊️Open source: This repository is covered by two licenses:
    • The HUGO Project and QGIS theme provided here are published under a permissive 🔑 MIT License.
    • The actual content of the web site is © QGIS.ORG amd Contributors and is made available under the Creative Commons-NonCommercial-Share-Alike-4.0 license. We chose this license to prevent third parties from hosting their own, possibly maliciously altered versions of the QGIS.org web site.

CC License

👏 A quick acknowledgement: The starting point for this site was the web site created by the community around jupiterbroadcasting.com . you can find their GitHub Repo here - although we have made so many changes, there probably isn't much left of the site we derived from in this repo.

🛒 Getting the Code

Navigate to your development directory

git clone https://github.com/qgis/qgis-hugo.git

🧑🏽‍💻 Development

First install hugo for your local machine:

📝 Note: we need to install the 'extended' hugo version which includes a SASS compiler. If you don't install the extended version you will get errors like this when compiling:

ERROR 2022/12/11 07:33:37 Rebuild failed: TOCSS: failed to transform 
"css/style.scss" (text/x-scss). Check your Hugo installation; you need 
the extended version to build SCSS/SASS.: this feature is not available 
in your current Hugo version, see https://goo.gl/YMrWcn for more information

You can find the extended version in the releases page.

Download

🐧 Linux:

Download the deb above and then do

sudo dpkg -i hugo_extended_0.107.0_linux-amd64.deb

🪟 Windows:

Follow these notes

🍏 macOS:

Follow these notes

⚙️ Setting up VSCode

If you are using VSCode, I recommend the following extensions:

  • Hugo Language and Syntax Support
  • Color Highlight

Clone the repo:

git clone https://github.com/qgis/qgis-hugo.git

Run the site:

Press Ctl-Shift-D then choose the following runner:

'Run dev using locally installed Hugo'

the click the green triangle next to the runner to start it.

Once the site is running, you can open it at:

http://localhost:1313

The site will automatically refresh any page you have open if you edit it and save your work. Magical eh?

Running End to End (e2e) Tests

Test files are located in test/e2e.

You need to have these extras installed:

pip install pytest pytest-base-url playwright

These tests exist to make sure code changes to this repository do not break how the site currently functions. They are intended to run on each commit to verify the site is working in expected order.

Read more on testing here.

Creating and Running Tests

  1. Navigate to the e2e test folder which is located in test/e2e.
  2. Create or edit a test file for the page or section you want to test and get coding, test files should start with the name test follow by the file name, example test_about_page.py.

Running tests in VSCode

We can enable built in pytest support in VSCode.

Note: Before running the tests, you need to install the dependencies listed in REQUIREMENTS.txt:

pip install -r REQUIREMENTS.txt

And playwright:

pip install playwright

These should be set up by default when you open this project under VSCode, but if needed you can configure the VSCode settings to set the base-url (search for @id:python.testing.pytestArgs Testing in the settings filter):

Testing options

Start the live debug server:

Debug Server

Now open the test explorer and run your tests:

Testing Run

Any failed tests will be marked in red as shown above.

Running from the command line:

pytest --base-url=http://localhost:1313

Running tests in docker

  1. Start the hugo server in a terminal window make dev.
  2. Run test in terminal window make tests

Note: To run the tests as described above, you need to have docker installed on your machine and the appropriate permissions to run docker commands.

Running as github action

There is a github action that will run the tests automatically on PR submission, merge.

See .github/workflows/e2e.yml

Content Harvesting

You can harvest data from various feeds using the fetch_feeds.py script. By default flickr harvesting is disabled in this script so run it manually and review the content to see if it is suitable for publication on our site.

./fetch_feeds.py --flickr=yes

This script is run nightly as a github action (see .github/workflows/update-feeds.yml).

Search Functionality

The search functionality uses both FuseJS and MarkJS.

The search functionality code is based on this Blog Post and GitHub Gist by Eddie Webb.

Content folders need to be excluded from search, by making them headless bundles - which we have done for the sustaining member and flagship user folders in content/. To make other content folders which are not rendered and included in search results, add an index.md file with the following content: headless = true.

Referencing URLs in templates

The site needs to work in production, where the links of the site are all below the root URL, and in staging, where the site is deployed to GitHub pages in a subpath. To ensure both deployment strategies work, please use the following method of constructing URLs in templates.

<a class="button is-primary" href="{{ "donate/" | absURL }}">

Note: We do not use a leading slash, only an ending slash.

📁 File naming conventions

  • Separate words in file names with hyphens e.g. windows-download.md
  • Avoid abbreviations in the words of your files
  • Write file names in lower case only
  • No spaces in file names

🤝 Contributing to this project

We welcome your contributions! All contributors are expected to sign a contributor license agreement (CLA) which you can see here. This process is automatically enabled when you create your first pull request via https://cla-assistant.io/.

CLA assistant

💮 Changing the templates

Page type Path
Landing Page themes/qgis/layouts/index.html
Top Level Pages themes/qgis/layouts/_default/single.html

🏠 Editing the landing (home) page

The content/_index.md is the content for the landing page. Just edit whatever you like there. The blocks shortcodes are described below.

📃 Adding a top level page

Create the content

Content pages are stored in the content folder. The top level documents there will be rendered with the top level page theming.

For example to add an about page, create content/about.md

The page will be accessible then at /about/

🖼️ Referencing Images and Media

Place images and media in static/img. Everything in static is referenced from the top level of the site e.g. static/img/foo.png would be referenced in markdown as /img/foo.png.

🌶️ Working with menus

There are two menus, the primary (1) menu which appears at the top of the page, and the secondary menu (2) which may appear beneath it depending on context.

Menus

Primary Menu Pages

For pages to appear in the top menu, you need to add an entry to config.toml for example the menu for the above about page will be:

[[menu.main]]
  name = "About"
  url = "/about/"
  weight = -110
  # pre = "<i class='fa-solid fa-clipboard-question mr-1'></i>"

Note: The pre item is commented out. If you uncomment it, it will place a font awesome icon before the text of the menu item.

Secondary Menu Pages

For pages to appear in the secondary menu, you need to add an entry to config.toml for example the menu for the documentation page will be:

[[menu.learning]]
  name = "Documentation"
  url = "/documentation/documentation-overview/"
  weight = -110
  #pre = "<i class='fa-solid fa-clipboard-question mr-1'></i>"
  [menu.learning.params]
    submenu = "documentation"

Use the submenu parameter to define which submenu the menu entry should be shown in. You can create as many submenu terms as you like, and then associate pages to these submenus in the front matter of your markdown documents.

Displaying a secondary menu

In order for a secondary menu to be displayed, your content page needs to specify the submenu name in the front matter e.g.:

Menus

Example front matter listing:

---
type: "page"
title: "Documentation Overview"
subtitle: "QGIS Documentation Resources"
draft: false
heroImage: "img/banners/banner2.png"
submenus: documentation
---

Note: Despite the pluralised name, you should only specify one submenu name.

All of the menu entries specified in config.toml with a matching submenus term will be shown in the secondary menu when you add this to the front matter. If you specify no submenus= entry in the front matter, the secondary menu will not be rendered.

Modifying the menu templates

The primary menu template is implemented in themes/qgis/layouts/partials/menu.html.

The secondary menu template is implemented in themes/qgis/layouts/partials/submenu.html.

Note: You typically will not need to edit the above files unless you are a developer.

🚧 Working with blocks

Blocks span the page from left to right and contain sub elements for title, description, link etc.

Block

Blocks are defined in themes/qgis/layouts/shortcodes/block. To use a block, simply add it to your markdown as per this example:

{{< block
    title="Block with more content"
    subtitle="Unleash your creativity and experience first 
    class cartographic design capabilities and design great
    maps for digital and print. "
>}}

If you want to include markdown content inside the block you can do it as inner content like this:

{{< block
    title="Block with more content"
    subtitle="Unleash your creativity and experience first 
    class cartographic design capabilities and design great 
    maps for digital and print. "
>}}
More details khdkjhksj dhjfhs dkj hsfdjkh fsd
{{< /block >}}

The options for a block are:

Name Description
title Title for the block
subtitle Subtitled for the block
link Optional: URL to have a link to at the bottom left of the block
link-text Mandatory if link provided: Text to show with the hyperlink.
link-class Optional and only used if link provided: Bulma class (e.g. is-primary) for the link button.
class defaults to is-primary. Use this to set the bulma class for the block.
animate defaults to false. Experimental support for animating blocks into place as they enter the viewport.
sub-block-side defaults to 'cover'. Choose which side (left, right) or cover. Use cover to span the content across the whole block. If an image is set, the image will cover the block or be placed left or right as indicated here.
image optional. Place your images into the same folder as the markdown file (so that they are 'bundle resources in hugo terminology') and then reference by the file name only e.g. "some-image.png".

Note: Do not include a leading slash in the image path!

🪪 Working with Boxes and Columns

We carry over the idea of boxes and columns from bulma. They can be used to arrange content in a side by side fashion or a grid of content boxes.

First a simple example:

{{< columns-start >}}
{{< column-start >}}
{{< box-start >}}
# Box 1

Normal markdown text....


{{< box-end >}}
{{< box-start >}}
# Box 2

Normal markdown text....


{{< box-end >}}
{{< column-end >}}
{{< columns-end >}}

Will render like this:

Columns1

To render the blocks side by side, we can make a small tweak like this:


{{< columns-start >}}
{{< column-start>}}
{{< box-start >}}
# Box 1

Normal markdown text....


{{< box-end >}}
{{< column-end >}}
{{< column-start>}}
{{< box-start >}}
# Box 2

Normal markdown text....


{{< box-end >}}
{{< column-end >}}
{{< columns-end >}}

Above you can see we close each column before setting the nextWill render like this:

Columns2

One last column arrangement example shows how we can use the bulma column sizes to define specific column sizes:


{{< columns-start >}}
{{< column-start class="is-one-third">}}
{{< box-start >}}
# Box 1

Normal markdown text....


{{< box-end >}}
{{< column-end >}}
{{< column-start class="is-two-thirds">}}
{{< box-start >}}
# Box 2

Normal markdown text....


{{< box-end >}}
{{< column-end >}}
{{< columns-end >}}

Above you can see we use the is-one-third / is-two-thirds classes on each column so they render like this:

Columns3

The content you write within boxes can be normal markdown and can use any of the shortcode components described in this readme. Here is an example from the download page showing a QR code block and a content card side by side in the grid.

Cards

🎬 Starting a box

Before starting your markdown content, start a card using the box-start shortcode so it lays out nicely in our grid:

{{< box-start >}}

This is the all-in-one stable release installer. The software 
you receive with the free download link and the download and
donate link is identical. For other Windows installer variants 
see here.

A box-start shortcode can take the following parameters:

Name Description
header A short piece of text to display in the card header
classes (Optional) Any bulma classes you want to have applied to the internal content section of the card.
ribbon A word or two to display at the top left of the box.
ribbon-classes A bulma class such as is-primary to set the style of the ribbon. See also the Bulma Ribbon page for other modifier classes that can be used.

Here is an example of a box with ribbon set:

{{< box-start  ribbon="Note!" ribbon-class="is-success">}}

Acceptance of sustaining members shall be subject to the discretion and approval of The Board,
who reserve the right to accept or reject applications for sustaining membership and
ongoing support memberships as deemed appropriate.

{{< box-end >}}

Box

🔚 Ending a box

When you are done writing your content, end a box using the box-end shortcode:

{{< box-end >}}

A box-end shortcode takes no parameters:

Image

The image shortcode can be used to place an image on the page occupying the same amount of space as a block:

Image

Sample useage:

{{< image
    image="soufriere.png"
>}}

If you prefer, you can supply a GIF and it will display animated. The image will be anchored to the left top of the block and then cropped according to the block dimensions.

There is a special option whereby you can combine both a static image preview and an animated GIF that will be visible when you mouse over the image. To do this you need to have two images, a PNG image and an GIF image. Typically you might record the GIF using an application like Peek. Once you have a GIF, you can extract the first frame like this (using ImageMagick):

convert 'image.gif[0]' image.png

To include the mouse over version, add an image element referencing the PNG, and then add gif=true as a parameter:

{{< image
    image="soufriere.png"
    gif=true
>}}

Note: The image names must have the same base name and you must use PNG and GIF images.

Hover Image

Content

If you are writing plain markdown, you can also wrap it in content shortcodes (instead of the card shortcode described above) like this:

{{< content-start classes="notification is-light" >}}

# Markdown header

Markdown content

{{< content-end >}}
Name Description
classes (Optional) Any bulma classes you want to have applied to the internal content section of the card.

Button

The button shortcode is a way to put a single button link element onto your page:

Cards

{{< button
fullwidth = "true"
icon = "fa-solid fa-calendar"
class = "is-success"
link = "showcase/user-group-events"
text = "User Group News" >}}

Note: We do not use a leading slash for internal links, only an ending slash. If you want the link to open in a new tab, start the link with https: or mailto:

Info Bar

The info-bar shortcode is a way to put a infographic style element onto your page:

Cards

{{< info-bar 
    "20+:years"
    "100%:open source"
    "450k+:Daily users" >}}

To use info-bar, pass it a collection of key-value pairs separated by : colons as illustrated above.

Icon Bar

The info-icons shortcode is a way to put a row of circular fontawesome icon elements onto your page:

Cards

{{< info-icons 
    "Linux:fa-brands fa-linux"
    "macOS:fa-brands fa-apple"
    "Windows:fa-brands fa-windows" >}}

To use icon-bar, pass it a collection of key-value pairs separated by : colons as illustrated above. The second value should be a fontawesome image name.

Image Bar

The image-bar shortcode is a way to put a row of circular image elements onto your page:

Cards

{{< image-bar 
    "Cartography:/img/map1.png"
    "Analysis:/img/map2.png"
    "Print:/img/map3.png" >}}

To use image-bar, pass it a collection of key-value pairs separated by : colons as illustrated above. The second value should be a path to an image.

Button Bar

The button-bar shortcode is a way to put a row of button link elements onto your page:

Cards

{{< button-bar 
    "fa-brands fa-windows mr-1:Windows:downloads/windows/"
    "fa-brands fa-apple mr-1:macOS:downloads/macos/"
    "fa-brands fa-linux mr-1:Linux:downloads/linux/"
 >}}

Note: We do not use a leading slash for internal links, only an ending slash. If you want the link to open in a new tab, start the link with https: or mailto:

To use button-bar, pass it a collection of key-value triplets separated by : colons as illustrated above.

  1. The first value should be a fontawesome image name.
  2. The second value should be the label for the button.
  3. The third value should be the link that clicking the button will lead to.

You can add as many buttons as you like to the bar, and they will be distributed evenly across the page.

Steps Bar

The steps-bar shortcode is a way to put a row of steps onto your page:

Cards

{{< steps-bar 
    "fa-solid fa-hand-holding-heart:Choose if you want to support the project:true"
    "fa-sharp fa-solid fa-solar-system:Choose your operating system:false"
    "fa-solid fa-download:Download:false"
 >}}

To use steps-bar, pass it a collection of key-value triplets separated by : colons as illustrated above.

  1. The first value should be a fontawesome image name.
  2. The second value should be the label for the step.
  3. The third value should be true or false indicating which step is active.

You can add as many steps as you like to the bar, and they will be distributed evenly across the page.

Example using them together

{{< image-bar
    "Cartography:map1.png"
    "Analysis:map1.png"
    "Print:map1.png" >}}

{{< info-icons
    "Linux:fa-brands fa-linux"
    "macOS:fa-brands fa-apple"
    "Windows:fa-brands fa-windows" >}}

{{< info-bar
    "20+:years"
    "100%:open source"
    "450k+:Daily users" >}}

🩳 Customising CSS

Brand Identity

Brand colours are established in config.toml.

Brand Colours

These are compiled into the SASS theme when Hugo builds the site. You can further modify the branding by overriding bulma variables. To do this, edit themes/qgis/assets/sass/bulma.sass and add your variables. Each bulma page includes a list of variables at the bottom of the page which can be used to override the default bulma styling for the various elements they provide. For example, we can to the variable list for bulma buttons and choose a property to modify:

Bulma Variable

Next, set a value for that variable in themes/qgis/assets/sass/bulma.sass:

Band SASS

Finally, to rather use the parameter defined in config.toml, you can use this syntax:

$navbar-background-color: {{ .Param "light2" }};

Bulma Extensions

We use various bulma css framework extension. If you need to add more, place them with the others in themes/qgis/assets/sass and then reference the addition in themes/qgis/assets/sass/bulma.sass (as shown in the example below). Always use the SASS version so that the them branding is properly applied. More bulma extensions can be found in

/* Extensions */
/* Steps - see https://github.com/aramvisser/bulma-steps */
@import "bulma-steps.sass"
/* Pricing table - see https://github.com/Wikiki/bulma-pricingtable */
@import "bulma-pricing-table.sass"
/* Badge - see https://github.com/CreativeBulma/bulma-badge/ */
@import "bulma-pricing-table.sass"

Other CSS Customizations

Put your customizations in themes/qgis/assets/css/custom.css.

We use a hugo minification and combining workflow - see the header layout in themes/qgis/layouts/partials/header.html.

About

Hugo static website for the new QGIS.org

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Sass 41.5%
  • JavaScript 31.1%
  • HTML 17.8%
  • Python 5.5%
  • CSS 3.5%
  • Makefile 0.4%
  • Other 0.2%