mirror of
https://github.com/acaloiaro/garbagespeak.com
synced 2026-07-21 18:29:08 +00:00
Add submission support / rework menus
This commit is contained in:
parent
e768c99db0
commit
8fb9646d2c
19 changed files with 263 additions and 175 deletions
120
README.md
120
README.md
|
|
@ -1,119 +1,23 @@
|
|||
# hugo-htmx-go-template
|
||||
# Garbage Speak
|
||||
|
||||
Make static Hugo sites dynamic with htmx and go
|
||||
A fun and useless website
|
||||
|
||||
This is a project template combining [Hugo](https://gohugo.io), [htmx](https://htmx.org), and an optional API server written in Go, using `html/template` or [templ](https://github.com/a-h/templ/) for HTML rendering.
|
||||
## Migrations
|
||||
|
||||
## Why?
|
||||
Migrations required `go-migrate` to be run locally:
|
||||
|
||||
Hugo is a fantastic static site building tool, and there are few things about Hugo that can or should be improved.
|
||||
`go install github.com/golang-migrate/migrate@v4`
|
||||
|
||||
The existence of this project template does not suggest that all static sites should be dynamic. If your site _can_ be static, it _should_ be static.
|
||||
### Adding migrations
|
||||
|
||||
Yet there are instances in which one might want to add dynamic functionality to static Hugo sites. That is the purpose of this project template. Not to make all static sites dynamic, but to provide a simple solution to add islands of dynamic behavior to static sites.
|
||||
`migrate create -ext sql -dir migrations -seq name_of_migration`
|
||||
|
||||
This allows us to build fast, easily deployable HTML content, with the added ability of meeting a new class dynamic behavior needs.
|
||||
### Running migrations
|
||||
|
||||
Example use cases include
|
||||
Migrate up
|
||||
|
||||
- Contact forms
|
||||
- Comment systems
|
||||
- Up/Down vote systems
|
||||
- You know ... website stuff
|
||||
`migrate -database ${POSTGRESQL_URL} -path migrations up`
|
||||
|
||||
You shouldn't have to reach for a SaaS product to offer dynamic content on your static sites.
|
||||
|
||||
## About
|
||||
|
||||
**First of all, what is meant by "project template"?**
|
||||
|
||||
This git repository is to be used as a template from which to create Hugo sites. It does not impose any constraints on how you use Hugo. It is, itself, a simple hugo project created with `hugo site new ...`. You can run `hugo serve` from this project's root directory and it will behave like every other Hugo site you've developed.
|
||||
|
||||
**So what _does_ this template provide?**
|
||||
|
||||
This template provides example code and simple developer tooling for running Hugo along with an optional API server, written in Go, using `html/template`.
|
||||
|
||||
**What developer tooling is provided?**
|
||||
|
||||
1. `bin/develop`: This utility both starts the hugo server (`hugo server`) and the API server (`go run server.go`) for development. If the user has `air` installed (https://github.com/cosmtrek/air), API server code will hot-reload when changes to server.go are made.
|
||||
2. `bin/build`: This utility builds a binary with your entire Hugo site embedded within. This allows Hugo sites to be deployed as a self-contained binary.
|
||||
|
||||
## Getting Started
|
||||
|
||||
**Clone this project template and initialize it**:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:acaloiaro/hugo-htmx-go-template.git ./my_new_site
|
||||
cd my_new_site
|
||||
# The theme 'ananke' is used here because it's the one used by Hugo's quickstart guide: https://gohugo.io/getting-started/quick-start/
|
||||
# You can use any theme with this project template, so long as you add htmx to its included scripts: <script type="text/javascript"src="/htmx.js"></script>
|
||||
# fetch-deps.sh does this automatically for the ananke theme
|
||||
git clone https://github.com/theNewDynamic/gohugo-theme-ananke ./themes/ananke
|
||||
bin/fetch-deps.sh
|
||||
go build -o bin/develop internal/cmd/develop/main.go
|
||||
go build -o bin/build internal/cmd/build/main.go
|
||||
mkdir public && touch public/.empty
|
||||
```
|
||||
|
||||
If you'll be using the API server, it's useful to install `air` to hot redeploy Go code changes when running `bin/develop`:
|
||||
|
||||
```bash
|
||||
go install github.com/cosmtrek/air@latest
|
||||
```
|
||||
|
||||
To make changes to `templ` templates (.templ files), first install `templ`. Using `templ` is optional. The [goodbye world](https://github.com/acaloiaro/hugo-htmx-go-template/blob/main/server.go#L83) example shows `templ` in action.
|
||||
|
||||
```bash
|
||||
go install github.com/a-h/templ/cmd/templ@latest
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
To start the development server(s), run `bin/develop`
|
||||
|
||||
Hugo will run on its develop port at [http://localhost:1313](http://localhost:1313) and the API server runs on [http://localhost:1314](http://localhost:1314).
|
||||
|
||||
Example content is available at: [http://localhost:1313/posts/hello-world/](http://localhost:1313/posts/hello-world/)
|
||||
|
||||
`bin/build` can be used to build fat binaries of your Hugo site, which will be available at [http://localhost:1314](http://localhost:1314) after running `build/server`.
|
||||
|
||||

|
||||
|
||||
## Changing `templ` templates
|
||||
|
||||
To use `templ` templates, you will need to `templ` installed. The `air` configuration watches for changes to `templ` files and automatically builds them.
|
||||
|
||||
## Deploy
|
||||
|
||||
Hugo sites made from this template project can be deployed in two ways.
|
||||
|
||||
### Traditional deployment
|
||||
|
||||
A traditional deployment is any deployment where Hugo content is deployed to an HTTP server that serves static content. Deploying Hugo content with this project template remains the same as a usual Hugo site.
|
||||
|
||||
However, to use the API server in production, you'll need to tell your static site content where to send HTTP requests.
|
||||
|
||||
Configure this in `config/production/hugo.toml`
|
||||
|
||||
If you've made your API available at `https://api.example.com`, add the following to `hugo.toml`:
|
||||
|
||||
```
|
||||
[Params]
|
||||
apiBaseUrl = 'https://api.example.com'
|
||||
```
|
||||
|
||||
The API server binary can be had by using `bin/build` to generate a fat binary, or simply compiling `server.go` directly: `go -o build/server server.go`
|
||||
|
||||
### Fat binary deployment
|
||||
|
||||
Fat binary deployment is made possible by `bin/build`. The `build/server` executable contains both the API server code and Hugo static site content.
|
||||
|
||||
No additional configuration is necessary to deploy a fat binary. Simply copy `build/server` to the system that will run it.
|
||||
|
||||
**Note:** To build fat binaries for different systems/architectures than the system performing the build, use the `GOOS` and `GOARCH` to change system/architecture, e.g.
|
||||
|
||||
Build a fat binary for OpenBSD and AMD64 architecture
|
||||
```bash
|
||||
GOOS=openbsd GOARCH=amd64 bin/build
|
||||
```
|
||||
Migrate down
|
||||
|
||||
`migrate -database ${POSTGRESQL_URL} -path migrations down`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
title: "Dictionary"
|
||||
---
|
||||
|
||||
Solutionizing a dictionary is a heavy lift. We encourage you to come back as your thought leaders have _temporarily_ put a pin in the dictionary initiative.
|
||||
Solutionizing a dictionary is a heavy lift. We encourage you to return at a later time, as your thought leaders have _temporarily_ put a pin in the dictionary initiative.
|
||||
|
||||
Many syncs are planned for this section's go-to-market. Rest assured it is coming.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,49 @@
|
|||
---
|
||||
title: "FAQ"
|
||||
toc: true
|
||||
---
|
||||
|
||||
## What is garbage speak?
|
||||
|
||||
Garbage speak is a community of thought leaders solving the world's language asks.
|
||||
|
||||
In this community we share out and collect all the key learnings of our ever-evolving language.
|
||||
|
||||
We are the value drivers, and we are here to futureproof the English language against stagnation.
|
||||
|
||||
We verb nouns and noun adjectives.
|
||||
|
||||
**We speak like our boss' bosses.**
|
||||
|
||||
## Can you show me the science?
|
||||
|
||||
Garbage speak is more feeling than science. While it often adheres to common formulas: nouning verbs, verbing nouns, and nouning adjectives. But truly novel garbage is a complex animal that can't be pinned down.
|
||||
|
||||
With that complexity in mind, the thought leaders have synced and we're happy to share out these garbage speak examples with accompanying analysis to help aspiring thought leaders navigate the garbage space.
|
||||
|
||||
---
|
||||
|
||||
**Garbage speak**: Is there a solve for this?
|
||||
|
||||
**Analysis**: The speaker has nouned the verb _solve_. They are asking if there is a solution.
|
||||
|
||||
---
|
||||
|
||||
**Garbage speak**
|
||||
Can we circle back to the ask here?
|
||||
|
||||
**Analysis**
|
||||
_Circle back_ is a garbage speak mainstay meaning "return" or "get back on topic". The verb _ask_ has been nouned.
|
||||
|
||||
---
|
||||
|
||||
**Garbage speak**
|
||||
We'd like to be intentional about the space we give our employees.
|
||||
|
||||
**Analysis**
|
||||
This is complex. _Intentional_ is being used not to communicate intention, but to communicate that the speaker is hip to therapy speak -- a sub genre of garbage speak. _Space_ is used in the same way, but it's serving a dual role. Its second role is that of a deeply ambiguous word that fills literal space in a sentence, making the speaker sound more like their boss. Is it physical space, emotional space (therapy speak), or some amalgamation of both (safe space)? It doesn't matter -- anything can be space in garbage speak.
|
||||
|
||||
|
||||
## What are the rules for thought leaders posting new garbage speak?
|
||||
|
||||
You can post any garbage speak seen in the wild, so long as it is not embellished and does not identify any individuals or companies.
|
||||
|
|
@ -12,7 +54,7 @@ If the garbage speak is _not_ proprietary, e.g. an internal company Slack conver
|
|||
|
||||
## Do I need to sign up to anything to become a thought leader?
|
||||
|
||||
Currently, no. But we may require registration in the future to combat spam / ensure that repeat embellishment offenders don't abuse the system.
|
||||
Yes. We require registration to combat spam / ensure that repeat embellishment offenders don't abuse the system.
|
||||
|
||||
## What's the go-to-market for future features?
|
||||
|
||||
|
|
|
|||
0
content/post.md
Normal file
0
content/post.md
Normal file
53
content/posts/new.md
Normal file
53
content/posts/new.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
title: New Garbage
|
||||
---
|
||||
|
||||
{{< html.inline >}}
|
||||
<form hx-post="{{ .Site.Params.apiBaseUrl }}/garbage/new">
|
||||
<div hx-target="this" hx-swap="innerHTML">
|
||||
<label for="title">A brief summary of the garbage</label>
|
||||
<input
|
||||
id="title"
|
||||
autofocus
|
||||
rquired
|
||||
type="text"
|
||||
name="title"
|
||||
style="width: 100%"
|
||||
placeholder="Provide an explanation, title, or some context"/>
|
||||
|
||||
<label for="garbage">Garbage Speak</label>
|
||||
<textarea id="garbage"
|
||||
required
|
||||
minlength="10"
|
||||
rows="3"
|
||||
autocorrect="off"
|
||||
wrap="soft"
|
||||
name="garbage"
|
||||
style="width: 100%"
|
||||
placeholder="This may be any garbage speak seen in the wild. Refer to the FAQ for what constitues garbage speak."></textarea>
|
||||
|
||||
<label for="url">URL where seen (optional)</label>
|
||||
<input
|
||||
id="url"
|
||||
optional
|
||||
type="text"
|
||||
name="url"
|
||||
style="width: 100%"
|
||||
placeholder="A public URL where this garbage was seen"/>
|
||||
|
||||
<label for="tags">Tags (optional)</label>
|
||||
<select id="tags" name="tags" multiple optional>
|
||||
<option>Nouned verb</option>
|
||||
<option>Verbed noun</option>
|
||||
<option>Nouned adjective</option>
|
||||
<option>Novel garbage</option>
|
||||
</select>
|
||||
<br>
|
||||
<br>
|
||||
<button>Post</button>
|
||||
</div>
|
||||
</form>
|
||||
{{< /html.inline >}}
|
||||
|
||||
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ title: Create Account
|
|||
|
||||
<br>
|
||||
<br>
|
||||
<button disabled>Create Account</button>
|
||||
<button disabled=true>Create Account</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
58
content/users/new.md
Normal file
58
content/users/new.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: Create Account
|
||||
---
|
||||
|
||||
{{< html.inline >}}
|
||||
<div class="auth-wrapper">
|
||||
<div class="auth-form">
|
||||
<form hx-post="{{ .Site.Params.apiBaseUrl }}/users/create">
|
||||
<div hx-target="this" hx-swap="innerHTML">
|
||||
<label for="username">Username</label>
|
||||
<input id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="desired username"
|
||||
hx-post="{{ .Site.Params.apiBaseUrl }}/users/new_user_validation"
|
||||
hx-indicator="#username-ind">
|
||||
<img id="username-ind" src="/img/bars.svg" class="htmx-indicator"/>
|
||||
|
||||
<label for="email">Email (we do not spam or sell information)</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="thot_ldr@email.com"
|
||||
hx-post="{{ .Site.Params.apiBaseUrl }}/users/new_user_validation"
|
||||
hx-indicator="#email-ind">
|
||||
<img id="email-ind" src="/img/bars.svg" class="htmx-indicator"/>
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
id="password
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="desired password"
|
||||
hx-post="{{ .Site.Params.apiBaseUrl }}/users/new_user_validation"
|
||||
hx-indicator="#password-ind">
|
||||
<img id="password-ind" src="/img/bars.svg" class="htmx-indicator"/>
|
||||
|
||||
<label for="password_confirmation">Password Confirmation</label>
|
||||
<input
|
||||
id="password_confirmation"
|
||||
type="text"
|
||||
name="password_confirmation"
|
||||
placeholder="desired password again"
|
||||
hx-post="{{ .Site.Params.apiBaseUrl }}/users/new_user_validation"
|
||||
hx-indicator="#password-conf-ind">
|
||||
<img id="password-conf-ind" src="/img/bars.svg" class="htmx-indicator"/>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<button disabled>Create Account</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{< /html.inline >}}
|
||||
|
||||
|
||||
0
content/users/post
Normal file
0
content/users/post
Normal file
14
hugo.toml
14
hugo.toml
|
|
@ -30,7 +30,7 @@ enableInlineShortcodes = true
|
|||
themeColor = "blue"
|
||||
|
||||
# if you set this to 0, only submenu trigger will be visible
|
||||
showMenuItems = 3
|
||||
showMenuItems = 5
|
||||
|
||||
# show selector to switch language
|
||||
showLanguageSelector = false
|
||||
|
|
@ -85,15 +85,11 @@ enableInlineShortcodes = true
|
|||
logoHomeLink = "/"
|
||||
|
||||
[languages.en.menu]
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "about"
|
||||
name = "What is Garbage Speak?"
|
||||
url = "/about/"
|
||||
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "garbage"
|
||||
name = "Latest Garbage"
|
||||
url = "/"
|
||||
weight = 1
|
||||
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "dictionary"
|
||||
|
|
@ -104,6 +100,12 @@ enableInlineShortcodes = true
|
|||
identifier = "faq"
|
||||
name = "FAQ"
|
||||
url = "/faq"
|
||||
weight = 2
|
||||
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "submit"
|
||||
name = "Submit"
|
||||
url = "/posts/new"
|
||||
|
||||
[module]
|
||||
# In case you would like to make changes to the theme and keep it locally in you repository,
|
||||
|
|
|
|||
0
migrations/000005_add_url_to_garbage.down.sql
Normal file
0
migrations/000005_add_url_to_garbage.down.sql
Normal file
1
migrations/000005_add_url_to_garbage.up.sql
Normal file
1
migrations/000005_add_url_to_garbage.up.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE ONLY public.garbages ADD COLUMN url text;
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
<li><a href="/users/create">Become thought leader (Create Account)</a></li>
|
||||
<li><a href="/users/create">Create Account</a></li>
|
||||
<li><a href="/users/login">Login</a></li>
|
||||
|
|
|
|||
|
|
@ -3,23 +3,23 @@
|
|||
<article class="post on-list">
|
||||
<h1 class="post-title">{{ .Title }}</h1>
|
||||
<div class="post-meta">
|
||||
{{- if .CreatedAt -}}
|
||||
<time class="post-date">
|
||||
{{- .CreatedAt.Format "2006-01-02" -}}
|
||||
</time>
|
||||
{{- end -}}
|
||||
|
||||
{{- with .Metadata.author -}}
|
||||
<span class="post-author">{{ . }}</span>
|
||||
{{- with .Username -}}
|
||||
<span>Submitter: <span class="post-author">{{ . }}</span></span>
|
||||
{{- end -}}
|
||||
|
||||
{{ if .Metadata.tags }}
|
||||
<span class="">
|
||||
{{ range .Metadata.tags }}
|
||||
{{- . -}}
|
||||
{{- . -}},
|
||||
{{ end }}
|
||||
</span>
|
||||
{{ end }}
|
||||
|
||||
{{- with .CreatedAt -}}
|
||||
<time class="post-date">
|
||||
{{- .Format "2006-01-02" -}}
|
||||
</time>
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
<style>
|
||||
.auth-wrapper{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.auth-wrapper .sign-form{
|
||||
max-width: 350px;
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.auth-wrapper h1{margin-bottom: 20px;}
|
||||
</style>
|
||||
|
||||
<div class="auth-wrapper">
|
||||
<div class="sign-form">
|
||||
<h1>Sign up</h1>
|
||||
|
||||
<form action="/users/create" method="POST" hx-target=".auth-wrapper">
|
||||
<input type="text" name="username">
|
||||
<input type="email" name="email">
|
||||
<input type="text" name="password">
|
||||
<input type="text" name="password">
|
||||
|
||||
<button class="btn btn-success">Sign In!</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<div class="auth-wrapper">
|
||||
<div class="sign-form">
|
||||
<form action="/users/login" method="POST" hx-target=".auth-wrapper">
|
||||
<input type="text" name="username">
|
||||
<input type="text" name="password">
|
||||
|
||||
<button class="btn btn-success">Sign In!</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
62
server.go
62
server.go
|
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
|
@ -39,10 +40,11 @@ import (
|
|||
// Garbage represents 'garbage' records from the database
|
||||
type Garbage struct {
|
||||
ID uuid.UUID
|
||||
OwnerID *uuid.UUID
|
||||
Username string
|
||||
Title string
|
||||
Content string
|
||||
Metadata map[string]any
|
||||
Url string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
|
|
@ -169,6 +171,9 @@ func main() {
|
|||
r.Get("/logout", logoutHandler)
|
||||
r.Get("/email_verification/{uev_id}", emailVerification)
|
||||
})
|
||||
r.Route("/garbage", func(r chi.Router) {
|
||||
r.Post("/new", createGarbageHandler)
|
||||
})
|
||||
|
||||
fmt.Printf("Starting API server on port 1314\n")
|
||||
if err := http.ListenAndServe("0.0.0.0:1314", r); err != nil {
|
||||
|
|
@ -365,6 +370,53 @@ func emailVerification(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, baseURL(), http.StatusFound)
|
||||
}
|
||||
|
||||
func createGarbageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
userID := sessions.GetString(r.Context(), "userID")
|
||||
if userID == "" {
|
||||
ise(errors.New("not logged in"), w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
ise(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
title := r.PostForm.Get("title")
|
||||
garbage := r.PostForm.Get("garbage")
|
||||
// TODO this is an arbitrary length that will likely need to change
|
||||
if len(garbage) == 10 {
|
||||
w.WriteHeader(400)
|
||||
return
|
||||
}
|
||||
|
||||
url := r.PostForm.Get("url")
|
||||
tags := r.Form["tags"]
|
||||
metadata := map[string]any{
|
||||
"tags": tags,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
db.QueryRow(ctx,
|
||||
"INSERT INTO garbages(title, content, url, metadata, owner_id) VALUES ($1, $2, $3, $4, $5)",
|
||||
title,
|
||||
garbage,
|
||||
url,
|
||||
metadata,
|
||||
userID)
|
||||
|
||||
//var buff = bytes.NewBufferString("")
|
||||
//tmpl := template.Must(template.ParseFiles("partials/users/created.html"))
|
||||
//err = tmpl.Execute(buff, map[string]any{"Email": email})
|
||||
//if err != nil {
|
||||
//ise(err, w)
|
||||
//return
|
||||
//}
|
||||
|
||||
w.Header().Add("hx-location", baseURL())
|
||||
}
|
||||
|
||||
// createAccount creates new accounts
|
||||
func createAccount(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
|
|
@ -460,7 +512,13 @@ func garbageBin(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
ctx := context.Background()
|
||||
posts := []*Garbage{}
|
||||
err := pgxscan.Select(ctx, db, &posts, `SELECT id,owner_id,title, content, metadata, created_at FROM garbages`)
|
||||
err := pgxscan.Select(
|
||||
ctx,
|
||||
db,
|
||||
&posts,
|
||||
`SELECT garbages.id, username, title, content, metadata, url, garbages.created_at
|
||||
FROM garbages
|
||||
JOIN users ON garbages.owner_id = users.id`)
|
||||
if err != nil {
|
||||
log.Println("error fetching garbage", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -74,3 +74,12 @@ button[disabled]{
|
|||
background-color: #cccccc;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
|
||||
textarea:invalid {
|
||||
border: 2px dashed red;
|
||||
}
|
||||
|
||||
textarea:valid {
|
||||
border: 2px solid lime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,12 @@
|
|||
white-space: nowrap;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: 20px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
&:not(:last-of-type):after {
|
||||
margin-left: 0.5rem;
|
||||
content: "|";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
<li class="menu__trigger">{{ $.Site.Params.MenuMore }} ▾</li>
|
||||
<li>
|
||||
<ul class="menu__dropdown">
|
||||
<div hx-get="{{ .Site.Params.apiBaseUrl }}/nav/user_items" hx-trigger="load" hx-swap="outerHTML">
|
||||
{{ range last (sub (len $.Site.Menus.main) $.Site.Params.showMenuItems) $.Site.Menus.main }}
|
||||
{{ if not .HasChildren }}
|
||||
<li><a href="{{ .URL }}" {{ if .Params.NewTab -}} target="_blank" {{- end }}>{{ .Name }}</a></li>
|
||||
|
|
@ -30,6 +29,6 @@
|
|||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<div hx-get="{{ .Site.Params.apiBaseUrl }}/nav/user_items" hx-trigger="load" hx-swap="outerHTML">
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
|
|||
Loading…
Reference in a new issue