Compare commits

...

8 Commits

Author SHA1 Message Date
c1714e9654 Update TODO
All checks were successful
Build and deploy website / build (push) Successful in 57s
Signed-off-by: Martin Berg Alstad <git@martials.no>
2025-07-03 19:10:56 +02:00
409c343a1b 👷 Merge into single docker compose file 2025-07-03 19:10:56 +02:00
fa58967164 👷 Update ref keys and master to develop on develop step 2025-07-03 19:10:56 +02:00
e0908c57a8 👷 Staging from develop branch 2025-07-03 19:10:56 +02:00
7030f70b50 Start updating paraglide to v2 2025-07-03 19:10:56 +02:00
5e7100c1e2 🔥 Remove prettier 2025-07-03 19:10:56 +02:00
82d1eea4f7 Update git domain 2025-07-03 19:10:56 +02:00
8d5c61cbaa 🎨 Fix lint errors using Biome 2025-07-03 19:10:55 +02:00
16 changed files with 90 additions and 1003 deletions

2
.env
View File

@ -1,3 +1,3 @@
DOMAIN="martials.no"
GIT_URL=https://git.$DOMAIN
GIT_URL=https://code.$DOMAIN
STATUS_URL="https://status.$DOMAIN/status/home"

View File

@ -4,9 +4,7 @@ on:
push:
branches:
- master
pull_request:
branches:
- master
- develop
jobs:
build:
@ -15,5 +13,9 @@ jobs:
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Run docker-compose
run: docker compose up -d --build
- name: Build production
run: docker compose up -d --build prod
if: gitea.ref == 'refs/heads/master'
- name: Build develop
run: docker compose up -d --build dev
if: gitea.ref == 'refs/heads/develop'

View File

@ -9,9 +9,10 @@
- [ ] Type slug of project
## CI/CD
- [ ] Staging environment
- [ ] Deploy to staging environment on push to master
- [ ] Deploy to production environment on push tag to master
- [x] Staging environment
- [x] Deploy to staging environment on push to develop
- [x] Deploy to production environment on push to master
- [ ] Staging environment .env file
## SEO
- [ ] Meta tags on each page

View File

@ -1,6 +1,5 @@
// @ts-check
import { defineConfig, envField } from "astro/config"
import paraglide from "@inlang/paraglide-astro"
import tailwindcss from "@tailwindcss/vite"
import sitemap from "@astrojs/sitemap"
import svelte from "@astrojs/svelte"
@ -9,6 +8,7 @@ import mdx from "@astrojs/mdx"
import icon from "astro-icon"
import { loadEnv } from "vite"
import { paraglideVitePlugin } from "@inlang/paraglide-js"
const { URL } = process.env.NODE_ENV
? loadEnv(process.env.NODE_ENV, process.cwd(), "")
@ -20,35 +20,37 @@ export default defineConfig({
output: "server",
i18n: {
defaultLocale: "nb",
locales: ["nb", "en"],
locales: ["nb", "en"]
},
integrations: [
sitemap(),
mdx(),
svelte(),
icon(),
paraglide({
project: "./project.inlang",
outdir: "./src/paraglide",
}),
icon()
],
adapter: node({
mode: "standalone",
mode: "standalone"
}),
vite: {
plugins: [tailwindcss()],
plugins: [
tailwindcss(),
paraglideVitePlugin({
project: "./project.inlang",
outdir: "./src/paraglide"
})
]
},
markdown: {
shikiConfig: {
theme: "catppuccin-mocha",
},
theme: "catppuccin-mocha"
}
},
env: {
schema: {
DOMAIN: envField.string({ context: "client", access: "public" }),
URL: envField.string({ context: "client", access: "public" }),
GIT_URL: envField.string({ context: "client", access: "public" }),
STATUS_URL: envField.string({ context: "client", access: "public" }),
},
},
STATUS_URL: envField.string({ context: "client", access: "public" })
}
}
})

View File

@ -1,9 +1,20 @@
services:
web:
container_name: martials.no
prod:
hostname: martials.no
container_name: "martials.no"
restart: always
build:
context: .
dockerfile: Dockerfile
ports:
- "4321:4321"
- "4321:4321"
dev:
hostname: dev.martials.no
container_name: "dev.martials.no"
restart: always
build:
context: .
dockerfile: Dockerfile
ports:
- "4322:4321"

6
middleware.ts Normal file
View File

@ -0,0 +1,6 @@
import { paraglideMiddleware } from "@/paraglide/server";
import { defineMiddleware } from "astro/middleware"
export const onRequest = defineMiddleware((context, next) => {
return paraglideMiddleware(context.request, () => next());
});

View File

@ -22,7 +22,6 @@
"@astrojs/sitemap": "^3.4.1",
"@astrojs/svelte": "^7.1.0",
"@iconify-json/pajamas": "^1.2.11",
"@inlang/paraglide-astro": "^0.4.1",
"@inlang/paraglide-js": "2.1.0",
"@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.1.11",
@ -36,25 +35,6 @@
},
"devDependencies": {
"daisyui": "^5.0.43",
"prettier": "^3.6.2",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-svelte": "^3.4.0",
"vite": "^7.0.0"
},
"prettier": {
"semi": false,
"singleQuote": false,
"plugins": [
"prettier-plugin-astro",
"prettier-plugin-svelte"
],
"overrides": [
{
"files": "**/*.astro",
"options": {
"parser": "astro"
}
}
]
}
}

887
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "nb",
"languageTags": ["nb", "en"],
"baseLocale": "nb",
"locales": [
"nb",
"en"
],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js"
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js"
],
"plugin.inlang.messageFormat": {
"pathPattern": "./messages/{languageTag}.json"
"pathPattern": "./messages/{locale}.json"
}
}

View File

@ -1,8 +1,9 @@
---
import { type NavLink, resolvePathname } from "@/utils/linking"
import { type NavLink } from "@/utils/linking"
import LocaleLink from "@/components/links/LocaleLink.astro"
import { deLocalizeHref } from "@/paraglide/runtime.js"
const pathname = resolvePathname(Astro.originPathname)
const pathname = deLocalizeHref(Astro.originPathname)
let paths: string[]
if (pathname === "/") {
@ -25,13 +26,13 @@ function getLink(path: string): NavLink {
{
paths.map((path, index) => (
<span>
{index != paths.length - 1 ? (
{ index != paths.length - 1 ? (
<span>
<LocaleLink to={getLink(path)}>{path}</LocaleLink>/
<LocaleLink to={ getLink(path) }>{ path }</LocaleLink>/
</span>
) : (
path
)}
) }
</span>
))
}

View File

@ -1,9 +1,10 @@
---
import LocaleLink from "./links/LocaleLink.astro"
import { type NavLink, resolvePathname } from "@/utils/linking"
import { type NavLink } from "@/utils/linking"
import { deLocalizeHref } from "@/paraglide/runtime"
const pathname = Astro.url.pathname
const currentPath = resolvePathname(pathname)
const currentPath = deLocalizeHref(pathname)
const isEnglish = pathname.startsWith("/en")
---

View File

@ -3,9 +3,9 @@ import Navbar from "./Navbar.astro"
import NavbarDrawer from "./NavbarDrawer.astro"
import HamburgerMenuButton from "./HamburgerMenuButton.astro"
import Breadcrumb from "../Breadcrumb.astro"
import { resolvePathname } from "@/utils/linking"
import { deLocalizeHref } from "@/paraglide/runtime"
const currentPath = `~${resolvePathname(Astro.originPathname)}`
const currentPath = `~${deLocalizeHref(Astro.originPathname)}`
const drawerToggleId = "header-drawer"
---

View File

@ -1,16 +1,16 @@
---
import { languageTag, type AvailableLanguageTag } from "@/paraglide/runtime"
import { localizePathname, type NavLink } from "@/utils/linking"
import { localizeHref, getLocale, type Locale } from "@/paraglide/runtime"
import { type NavLink } from "@/utils/linking"
import type { ComponentProps } from "@/types/props"
interface Props extends ComponentProps {
to: NavLink
lang?: AvailableLanguageTag
lang?: Locale
}
const { to, class: clazz, lang = languageTag() } = Astro.props
const { to, class: clazz, lang = getLocale() } = Astro.props
---
<a href={localizePathname(to, lang)} class={clazz}>
<a href={localizeHref(to, { locale: lang })} class={clazz}>
<slot />
</a>

View File

@ -3,7 +3,7 @@ import * as m from "@/paraglide/messages"
import Layout from "@/layouts/Layout.astro"
import BadgeList from "@/components/badge/BadgeList.astro"
import GiteaLink from "@/components/links/GiteaLink.astro"
import { languageTag } from "@/paraglide/runtime"
import { getLocale } from "@/paraglide/runtime"
import { getEntry, render } from "astro:content"
import { Image } from "astro:assets"
import dayjs from "dayjs"
@ -16,7 +16,10 @@ interface Props {
const { project } = Astro.props
const entry = await getEntry("projects", project)
const { Content } = await render(entry!)
if (!entry) {
throw new Error("Project not found")
}
const { Content } = await render(entry)
const {
lang,
title,
@ -28,14 +31,14 @@ const {
source,
createdAt,
updatedAt,
} = entry!.data
} = entry.data
function localeDateString(isoString: string): string {
let template = "DD-MM-YYYY"
if (languageTag() === "nb") {
if (getLocale() === "nb") {
template = "DD/MM/YYYY"
}
return dayjs(isoString).locale(languageTag()).format(template)
return dayjs(isoString).locale(getLocale()).format(template)
}
---

View File

@ -2,7 +2,7 @@
import Footer from "@/components/Footer.astro"
import Header from "@/components/header/Header.astro"
import Breadcrumb from "@/components/Breadcrumb.astro"
import { languageTag } from "@/paraglide/runtime"
import { getLocale } from "@/paraglide/runtime"
interface Props {
title: string
@ -16,7 +16,7 @@ const mainClass =
---
<!doctype html>
<html lang={languageTag()} dir={"ltr"}>
<html lang={getLocale()} dir={"ltr"}>
<head>
<meta charset="UTF-8" />
<meta name="author" content="Martin Berg Alstad" />

View File

@ -1,4 +1,3 @@
import type { AvailableLanguageTag } from "@/paraglide/runtime.js"
import type { AbsolutePathname, Project } from "@/types/types.ts"
interface TranslatedPathnames {
@ -22,8 +21,6 @@ const paths: Set<NavLink> = new Set([
"/uses",
])
const projectPaths: Set<string> = new Set<string>(["homepage", "sb1budget"])
/**
* Defines the localized pathnames for the site.
* The key must be used to navigate to the correct path.
@ -38,49 +35,3 @@ for (const path of paths) {
en: `/en${path}`,
}
}
export function localizePathname(
pathname: NavLink,
locale: AvailableLanguageTag,
): string {
const pathnameParts = pathname.split("/")
const firstSegment: AbsolutePathname = `/${pathnameParts[1]}`
if (pathnames[firstSegment]) {
const localizedPathname = pathnames[firstSegment][locale]
const rest = pathnameParts.slice(2)
if (rest.length > 0) {
return `${localizedPathname}/${rest.join("/")}`
} else {
return localizedPathname
}
}
return pathname
}
export function resolvePathname(pathname: string): AbsolutePathname {
if (pathname.startsWith("/en")) {
return pathname.slice(3) as AbsolutePathname
}
return pathname as AbsolutePathname
}
export function isAbsolutePathname(path: string): path is AbsolutePathname {
return path.startsWith("/")
}
export function isNavLink(path: string): path is NavLink {
if (path.startsWith("/en")) {
path = path.slice(2)
}
if (paths.has(path as NavLink)) {
return true
}
const pathSplit = path.split("/").slice(1)
return (
pathSplit.length === 2 &&
pathSplit[0] === "projects" &&
projectPaths.has(pathSplit[1])
)
}