First steps on dynamic content
- Removed SEO for now - Read meta tag values from YAML - Templates embedded into binary
This commit is contained in:
parent
281e666be8
commit
2080180985
|
@ -0,0 +1,26 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
func readConfig(configFilePath string) (resumeConfig *Resume, err error) {
|
||||
if configFilePath == "" {
|
||||
configFilePath = "./data/resume.yaml"
|
||||
}
|
||||
_, err = os.Stat(configFilePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
configBytes, err := os.ReadFile(configFilePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = yaml.Unmarshal(configBytes, &resumeConfig)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
# Meta tag configuration
|
||||
# All keys correspond to a meta tag name attribute, and value content attribute
|
||||
# e.g. <meta name="robots" value="index, follow">
|
||||
meta:
|
||||
# Set the content for the robots meta tag (noindex to disable search engine indexing)
|
||||
robots: "index, follow"
|
||||
language: "en-EN"
|
||||
author: "Job Applicant"
|
||||
theme-color: "#bd93f9"
|
||||
title: "Go-Resume - dynamic resume"
|
||||
description: "Software Developer"
|
||||
|
2
go.mod
2
go.mod
|
@ -1,3 +1,5 @@
|
|||
module github.com/0ranki/go-resume
|
||||
|
||||
go 1.21
|
||||
|
||||
require gopkg.in/yaml.v3 v3.0.1
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
61
main.go
61
main.go
|
@ -5,43 +5,50 @@ import (
|
|||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"slices"
|
||||
)
|
||||
|
||||
//go:embed "static/css/*.css"
|
||||
//go:embed "static/css/*.css" "templates/*.html"
|
||||
var static embed.FS
|
||||
|
||||
func home(w http.ResponseWriter, r *http.Request) {
|
||||
templateFiles := []string{
|
||||
"./templates/index.html",
|
||||
"./templates/jsonLd.html",
|
||||
"./templates/metatag.html",
|
||||
"./templates/githubCorner.html",
|
||||
}
|
||||
tmpl, err := template.ParseFiles(templateFiles...)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
err = tmpl.Execute(w, nil)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
//func css(w http.ResponseWriter, r *http.Request) {
|
||||
// staticFileServer := http.FileServer(http.FS(static))
|
||||
// mime.AddExtensionType(".css", "text/css")
|
||||
// staticFileServer.ServeHTTP(w, r)
|
||||
//}
|
||||
var templates map[string]*template.Template
|
||||
|
||||
func main() {
|
||||
readConfig("")
|
||||
staticFileServer := http.FileServer(http.FS(static))
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", home)
|
||||
mux.HandleFunc("/light", home)
|
||||
mux.HandleFunc("/dark", home)
|
||||
mux.Handle("/static/", staticFileServer)
|
||||
|
||||
slog.Info("Starting go-resume server, listening on port 3000")
|
||||
err := http.ListenAndServe(":3000", mux)
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
|
||||
func home(w http.ResponseWriter, r *http.Request) {
|
||||
acceptedPages := []string{"/", "/light", "/dark"}
|
||||
if !slices.Contains(acceptedPages, r.URL.Path) {
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
templateFiles := []string{
|
||||
"templates/index.html",
|
||||
"templates/metatag.html",
|
||||
"templates/githubCorner.html",
|
||||
}
|
||||
tmpl, err := template.ParseFS(static, templateFiles...)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||
}
|
||||
data, err := readConfig("")
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||
}
|
||||
err = tmpl.Execute(w, *data)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,3 @@ body {
|
|||
@media screen and (min-width: 768px) {
|
||||
.has-text-right-in-desktop {
|
||||
text-align: right; } }
|
||||
|
||||
.ads-square {
|
||||
min-width: 250px;
|
||||
min-height: 100px; }
|
||||
|
|
|
@ -90,7 +90,3 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.ads-square {
|
||||
min-width: 250px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
20%,
|
||||
60% {
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
80% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
|
@ -74,7 +74,3 @@ body {
|
|||
@media screen and (min-width: 768px) {
|
||||
.has-text-right-in-desktop {
|
||||
text-align: right; } }
|
||||
|
||||
.ads-square {
|
||||
min-width: 250px;
|
||||
min-height: 100px; }
|
||||
|
|
13
structs.go
13
structs.go
|
@ -1,5 +1,9 @@
|
|||
package main
|
||||
|
||||
type Resume struct {
|
||||
Meta Meta `yaml:"meta"`
|
||||
}
|
||||
|
||||
type job struct {
|
||||
Company string `yaml:"company"`
|
||||
Location string `yaml:"location"`
|
||||
|
@ -34,3 +38,12 @@ type social struct {
|
|||
}
|
||||
|
||||
type socials []social
|
||||
|
||||
type Meta struct {
|
||||
Language string `yaml:"language"`
|
||||
Author string `yaml:"author"`
|
||||
Title string `yaml:"title"`
|
||||
Description string `yaml:"description"`
|
||||
Robots string `yaml:"robots"`
|
||||
ThemeColor string `yaml:"theme-color"`
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{{ define "githubCorner" }}
|
||||
<a href="https://github.com/mazipan/bulma-resume-template" class="github-corner" aria-label="View source on GitHub">
|
||||
<a href="https://github.com/0ranki/go-resume" class="github-corner" aria-label="View source on GitHub">
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" style="
|
||||
fill: #000000;
|
||||
color: #fff;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html lang="en">
|
||||
|
||||
<head>
|
||||
{{ template "meta" }}
|
||||
{{ template "meta" .Meta }}
|
||||
<link rel="stylesheet" href="/static/css/dark-style.css" />
|
||||
</head>
|
||||
|
||||
|
@ -146,7 +146,7 @@
|
|||
|
||||
<footer class="footer">
|
||||
<div class="content has-text-centered">
|
||||
<a href="<%= content.config.publicPath %>/light">See Light Theme</a>
|
||||
<a href="/light">See Light Theme</a>
|
||||
<br />
|
||||
Copyright © 2018-2019 by
|
||||
<a href="https://mazipan.space">Irfan Maulana</a>
|
||||
|
@ -155,7 +155,6 @@
|
|||
|
||||
<footer class="line has-background-primary"></footer>
|
||||
|
||||
{{ template "jsonLd" }}
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,78 +0,0 @@
|
|||
{{ define "jsonLd" }}
|
||||
<!-- FROM jsonLd.ejs -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebSite",
|
||||
"url": "https://www.mazipan.github.io/",
|
||||
"name": "Irfan Maulana | Front End Developer",
|
||||
"author": "Irfan Maulana",
|
||||
"image": "http://mazipan.github.io/images/irfan-maulana.jpg",
|
||||
"description": "Irfan Maulana is Front End Developer from Indonesia - Man that craft some code to build a beauty and readable code, experienced in web and desktop technology.",
|
||||
"sameAs": [
|
||||
"https://www.facebook.com/mazipanneh",
|
||||
"https://instagram.com/maz_ipan",
|
||||
"https://twitter.com/Maz_Ipan",
|
||||
"https://id.linkedin.com/in/irfanmaulanamazipan",
|
||||
"https://www.slideshare.net/IrfanMaulana21",
|
||||
"https://github.com/mazipan"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
"email": "mailto:mazipanneh@gmail.com",
|
||||
"image": "http://mazipan.github.io/images/irfan-maulana.jpg",
|
||||
"jobTitle": "Software Engineer",
|
||||
"name": "Irfan Maulana",
|
||||
"url": "https://www.mazipan.github.io/",
|
||||
"sameAs": [
|
||||
"https://www.facebook.com/mazipanneh",
|
||||
"https://instagram.com/maz_ipan",
|
||||
"https://twitter.com/Maz_Ipan",
|
||||
"https://id.linkedin.com/in/irfanmaulanamazipan",
|
||||
"https://www.slideshare.net/IrfanMaulana21",
|
||||
"https://github.com/mazipan"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"item": {
|
||||
"@id": "http://mazipan.github.io/",
|
||||
"name": "Home",
|
||||
"image": "http://mazipan.github.io/images/irfan-maulana.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"item": {
|
||||
"@id": "http://mazipan.github.io/demo/",
|
||||
"name": "Demo",
|
||||
"image": "http://mazipan.github.io/images/irfan-maulana.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 3,
|
||||
"item": {
|
||||
"@id": "http://mazipan.github.io/bulma-resume-template",
|
||||
"name": "bulma-resume-template",
|
||||
"image": "https://mazipan.github.io/bulma-resume-template/logo.png"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
|
@ -1,66 +1,26 @@
|
|||
{{ define "meta" }}
|
||||
<meta name="robots" content="index, follow" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=7" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<meta name="language" content="en-EN" />
|
||||
<meta name="author" content="Irfan Maulana" />
|
||||
<title>Bulma Resume Template</title>
|
||||
<meta name="description" content="Free Resume/CV Page Template with Bulma CSS by Irfan Maulana" />
|
||||
|
||||
<meta property="og:title" content="Bulma Resume Template" />
|
||||
<meta property="og:description" content="Free Resume/CV Page Template with Bulma CSS by Irfan Maulana" />
|
||||
|
||||
<meta name="twitter:title" content="Bulma Resume Template" />
|
||||
<meta name="twitter:description" content="Free Resume/CV Page Template with Bulma CSS by Irfan Maulana" />
|
||||
<!-- Dynamic tags -->
|
||||
<meta name="robots" content="{{ .Robots }}" /> <!-- FROM YAML -->
|
||||
<meta name="language" content="{{ .Language }}" /> <!-- FROM YAML -->
|
||||
<meta name="author" content="{{ .Author }}" /> <!-- FROM YAML -->
|
||||
<meta name="description" content="{{ .Description }}" /> <!-- FROM YAML -->
|
||||
<meta name="theme-color" content="{{ .ThemeColor }}" /> <!-- FROM YAML -->
|
||||
<!-- Dynamic tags end -->
|
||||
|
||||
<title>AUTHOR FROM YAML</title> <!-- FROM YAML -->
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="https://cloud.oranki.net/apps/theming/favicon?v=2659fc51" />
|
||||
<meta name="theme-color" content="#bd93f9" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com/css?family=Raleway" />
|
||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com/css?family=Raleway" />
|
||||
<link rel="preload" href="https://fonts.googleapis.com/css?family=Raleway" as="style"
|
||||
onload="this.onload=null;this.rel='stylesheet'" />
|
||||
<link rel="preload" href="https://fonts.googleapis.com/css?family=Raleway" as="style" onload="this.onload=null;this.rel='stylesheet'" />
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway" />
|
||||
</noscript>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/dark-style.css" />
|
||||
<link rel="stylesheet" href="/static/css/github-corner.css" />
|
||||
|
||||
|
||||
<style>
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
20%,
|
||||
60% {
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
80% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
{{ end }}
|
Loading…
Reference in New Issue