Merge pull request #377 from nunocoracao/subnavigation-feature-branch

 Add sub-navigation and nested menus
This commit is contained in:
Nuno Coração 2023-01-14 21:58:42 +00:00 committed by GitHub
commit d569a0146e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 330 additions and 38 deletions

View file

@ -33,6 +33,9 @@ Blowfish is designed to be a powerful, lightweight theme for [Hugo](https://gohu
- Support for multiple authors
- Support for series of articles
- Flexible with any content types, taxonomies and menus
- Support for header and footer menus
- Support for nested menus
- Support for sub-navigation menu
- Multilingual content support inlcuding support for RTL languages
- Ability to link to posts on third-party websites
- Buymeacoffee integration

View file

@ -1433,6 +1433,10 @@ select {
margin-right: -0.5rem;
}
.mr-1 {
margin-right: 0.25rem;
}
.ml-auto {
margin-left: auto;
}
@ -1673,6 +1677,10 @@ select {
flex-wrap: wrap;
}
.items-end {
align-items: flex-end;
}
.items-center {
align-items: center;
}
@ -1707,6 +1715,18 @@ select {
margin-left: calc(1.25rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
}
.place-self-center {
place-self: center;
}
@ -2021,6 +2041,10 @@ select {
padding-left: 0.5rem;
}
.pb-3 {
padding-bottom: 0.75rem;
}
.pl-\[24px\] {
padding-left: 24px;
}
@ -2029,6 +2053,10 @@ select {
padding-right: 24px;
}
.pt-2 {
padding-top: 0.5rem;
}
.pt-16 {
padding-top: 4rem;
}
@ -2116,6 +2144,10 @@ select {
font-weight: 500;
}
.font-light {
font-weight: 300;
}
.uppercase {
text-transform: uppercase;
}
@ -3033,6 +3065,25 @@ body:has(#menu-controller:checked) {
z-index: 100;
}
.nested-menu:hover + .menuhide {
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
}
.menuhide:hover {
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
}
.menuhide {
visibility: hidden;
opacity: 0;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
z-index: 1000;
}
.first\:mt-8:first-child {
margin-top: 2rem;
}
@ -3513,20 +3564,11 @@ body:has(#menu-controller:checked) {
padding-right: 1.5rem;
}
.sm\:py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.sm\:py-24 {
padding-top: 6rem;
padding-bottom: 6rem;
}
.sm\:pt-10 {
padding-top: 2.5rem;
}
.sm\:pl-6 {
padding-left: 1.5rem;
}

View file

@ -419,7 +419,25 @@ body:has(#menu-controller:checked) {
}
}
.medium-zoom-image--opened {
z-index: 100;
z-index: 100;
}
.nested-menu:hover + .menuhide {
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
}
.menuhide:hover {
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
}
.menuhide {
visibility: hidden;
opacity: 0;
transition: visibility 0.3s, opacity 0.3s ease-in-out ;
z-index: 1000;
}

View file

@ -0,0 +1,12 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
clip-rule="evenodd"
/>
</svg>

After

Width:  |  Height:  |  Size: 317 B

View file

@ -15,6 +15,33 @@
# pageRef = "posts"
# weight = 10
#[[main]]
# name = "Parent"
# weight = 20
#[[main]]
# name = "example sub-menu 1"
# parent = "Parent"
# pageRef = "posts"
# weight = 20
#[[main]]
# name = "example sub-menu 2"
# parent = "Parent"
# pageRef = "posts"
# weight = 20
#[[subnavigation]]
# name = "An interesting topic"
# pageRef = "tags/interesting-topic"
# weight = 10
#[[subnavigation]]
# name = "My Awesome Category"
# pre = "github"
# pageRef = "categories/awesome"
# weight = 20
#[[main]]
# name = "Categories"
# pageRef = "categories"

View file

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View file

@ -195,6 +195,57 @@ Menu links will be sorted from lowest to highest `weight`, and then alphabetical
Both menus are completely optional and can be commented out if not required. Use the template provided in the file as a guide.
### Nested menus
The theme also supports nested menus. In order to use them you just need to define a parent entry in `menu.toml` and its sub-menus using the `parent` parameter to reference the parent. All properties can be used for sub-menus. Note that `pageRef` and `url` will be ignored for the parent entry. Nested menus is only available in the main menu not for the footer.
```toml
# config/_default/menus.toml
[[main]]
name = "Parent"
weight = 20
[[main]]
name = "sub-menu 1"
parent = "Parent"
pageRef = "samples"
weight = 20
[[main]]
name = "sub-menu 2"
parent = "Parent"
pageRef = "samples"
weight = 20
[[main]]
name = "sub-menu 3"
parent = "Parent"
pre = "github"
pageRef = "samples"
weight = 20
```
### Sub-Navigation menu
Additionally, you can also configure a sub-navigation menu. Just define new menu entries as `subnavigation` in `menu.toml`. This will render a second line with caregories below the main header menu.
```toml
# config/_default/menus.toml
[[subnavigation]]
name = "An interesting topic"
pageRef = "tags/interesting-topic"
weight = 10
[[subnavigation]]
name = "My Awesome Category"
pageRef = "categories/awesome"
weight = 20
```
## Thumbnails & Backgrounds
Blowfish was built so it would be easy to add visual support to your articles. If your familiar with Hugo article strucutre, you just need to place an image file (almost all formats are supported bue we recommend `.png` or `.jpg`) that starts with `feature*` inside your article folder. And that's it, Blowfish will then able to both use the image as a thumbnail within your website as well as for <a target="_blank" href="https://oembed.com/">oEmbed</a> cards across social platforms.
@ -205,4 +256,4 @@ Additionally, Blowfish also supports background hero images in articles and list
## Detailed configuration
The steps above are the bare minimum configuration. If you now run `hugo server` you will be presented with a blank Blowfish website. Detailed configuration is covered in the [Configuration]({{< ref "configuration" >}}) section.
The steps above are the bare minimum configuration. If you now run `hugo server` you will be presented with a blank Blowfish website. Detailed configuration is covered in the [Configuration]({{< ref "configuration" >}}) section.

View file

@ -147,4 +147,4 @@
</script>
{{ end }}
{{ end }}
</head>
</head>

View file

@ -1,6 +1,6 @@
<div style="padding-left:0;padding-right:0;padding-top:2px;padding-bottom:3px"
class="flex items-center justify-between px-4 py-6 sm:px-6 md:justify-start space-x-3">
{{ if .Site.Params.Logo -}}
{{ if .Site.Params.Logo }}
{{ $logo := resources.Get .Site.Params.Logo }}
{{ if $logo }}
<div>
@ -17,20 +17,17 @@
<div class="flex flex-1 items-center justify-between">
<nav class="flex space-x-3">
<a href="{{ "" | relLangURL }}" class="text-base font-medium text-gray-500 hover:text-gray-900">{{ .Site.Title | markdownify
<a href="{{ "" | relLangURL }}" class="text-base font-medium text-gray-500 hover:text-gray-900">{{
.Site.Title | markdownify
| emojify }}</a>
</nav>
<div class="hidden md:flex items-center space-x-5 md:ml-12">
<nav class="hidden md:flex items-center space-x-5 md:ml-12">
{{ if .Site.Menus.main }}
{{ range .Site.Menus.main }}
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:") (strings.HasPrefix .URL "https:") }} target="_blank"{{ end }} class="text-base font-medium text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ partial "icon.html" .Pre }}
{{ if and .Pre .Name }} &nbsp; {{ end }}
{{ .Name | markdownify | emojify }}
</a>
{{ partial "header/header-option.html" . }}
{{ end }}
{{ end }}
@ -38,12 +35,12 @@
{{ if .Site.Params.enableSearch | default false }}
<button id="search-button" class="text-base hover:text-primary-600 dark:hover:text-primary-400"
title="{{ i18n "search.open_button_title" }}">
title="{{ i18n " search.open_button_title" }}">
{{ partial "icon.html" "search" }}
</button>
{{ end }}
{{/* Appearance switch */}}
{{ if .Site.Params.footer.showAppearanceSwitcher | default false }}
<div
@ -59,7 +56,7 @@
</div>
{{ end }}
</div>
</nav>
<div class="flex md:hidden items-center space-x-5 md:ml-12">
<span></span>
@ -68,7 +65,7 @@
{{ if .Site.Params.enableSearch | default false }}
<button id="search-button-mobile" class="text-base hover:text-primary-600 dark:hover:text-primary-400"
title="{{ i18n "search.open_button_title" }}">
title="{{ i18n " search.open_button_title" }}">
{{ partial "icon.html" "search" }}
</button>
{{ end }}
@ -97,28 +94,71 @@
<div id="menu-wrapper" style="padding-top:5px;"
class="fixed inset-0 z-30 invisible w-screen h-screen m-auto overflow-auto transition-opacity opacity-0 cursor-default bg-neutral-100/50 backdrop-blur-sm dark:bg-neutral-900/50">
<ul
class="flex movedown flex-col w-full px-6 py-6 mx-auto overflow-visible list-none ltr:text-right rtl:text-left max-w-7xl sm:px-14 md:px-24 lg:px-32 sm:py-10 sm:pt-10">
<li class="mb-1">
<span class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400">{{ partial
class="flex space-y-2 mt-3 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none ltr:text-right rtl:text-left max-w-7xl">
<li>
<span
class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400">{{
partial
"icon.html"
"xmark" }}</span>
</li>
{{ if .Site.Menus.main }}
{{ range .Site.Menus.main }}
<li class="mb-1">
<a {{ if or (strings.HasPrefix .URL "http:") (strings.HasPrefix .URL "https:") }} target="_blank"{{ end }} class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2"
href="{{ .URL }}" title="{{ .Title }}">
<span class="inline-block align-text-bottom">{{ partial "icon.html" .Pre }}</span>
{{ if and .Pre .Name }} &nbsp; {{ end }}
{{ .Name | markdownify | emojify }}
</a>
</li>
{{ partial "header/header-mobile-option.html" . }}
{{ end }}
{{ end }}
</ul>
{{ if .Site.Menus.subnavigation }}
<hr>
<ul
class="flex mt-4 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none ltr:text-right rtl:text-left max-w-7xl">
{{ range .Site.Menus.subnavigation }}
<li class="mb-1">
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:"
) }} target="_blank" {{ end }} class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-3" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-sm font-sm text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>
</li>
{{ end }}
</ul>
{{ end }}
</div>
</label>
</div>
</div>
{{ if .Site.Menus.subnavigation }}
<div class="flex pb-3 flex-col items-end justify-between md:justify-start space-x-3" {{ if .Site.Params.Logo }} style="margin-top:-15px" {{ end }}>
<div class="hidden md:flex items-center space-x-5">
{{ range .Site.Menus.subnavigation }}
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:" ) }}
target="_blank" {{ end }} class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-xs font-light text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>
{{ end }}
</div>
</div>
{{ end }}

View file

@ -0,0 +1,31 @@
<li class="mt-1">
<a class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-bg font-bg text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
<span>
{{ partial "icon.html" "chevron-down" }}
</span>
</a>
</li>
{{ range .Children }}
<li class="mt-1">
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:"
) }} target="_blank" {{ end }} class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-sm font-small text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>
</li>
{{ end }}
<li class="mb-2"></li>

View file

@ -0,0 +1,13 @@
<li class="mt-1">
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:"
) }} target="_blank" {{ end }} class="flex items-center">
{{ if .Pre }}
<div {{ if and .Pre .Name}} class="mr-2" {{ end }}>
{{ partial "icon.html" .Pre }}
</div>
{{ end }}
<p class="text-bg font-bg text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>
</li>

View file

@ -0,0 +1,5 @@
{{ if .HasChildren }}
{{ partial "header/header-mobile-option-nested.html" . }}
{{ else }}
{{ partial "header/header-mobile-option-simple.html" . }}
{{ end }}

View file

@ -0,0 +1,34 @@
<div>
<div class="cursor-pointer flex items-center nested-menu">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<a class="text-base font-medium text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</a>
<span>
{{ partial "icon.html" "chevron-down" }}
</span>
</div>
<div class="absolute menuhide">
<div class="pt-2 p-5 mt-2 rounded-xl backdrop-blur shadow-2xl">
<div class="flex flex-col space-y-3">
{{ range .Children }}
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:" ) }}
target="_blank" {{ end }} class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-sm font-sm text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>
{{ end }}
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,11 @@
<a href="{{ .URL }}" {{ if or (strings.HasPrefix .URL "http:" ) (strings.HasPrefix .URL "https:" ) }} target="_blank" {{
end }} class="flex items-center">
{{ if .Pre }}
<span {{ if and .Pre .Name}} class="mr-1" {{ end }}>
{{ partial "icon.html" .Pre }}
</span>
{{ end }}
<p class="text-base font-medium text-gray-500 hover:text-gray-900" title="{{ .Title }}">
{{ .Name | markdownify | emojify }}
</p>
</a>

View file

@ -0,0 +1,5 @@
{{ if .HasChildren }}
{{ partial "header/header-option-nested.html" . }}
{{ else }}
{{ partial "header/header-option-simple.html" . }}
{{ end }}