Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
363497d354 | ||
|
|
b97c9ea3ee | ||
|
|
82def98e7e |
@@ -439,9 +439,6 @@ Alias "/static" "/var/www/jc/static/"
|
|||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
Alias "/robots.txt" "/var/www/jc/static/robots.txt"
|
Alias "/robots.txt" "/var/www/jc/static/robots.txt"
|
||||||
Alias "/.well-known/security.txt" "/var/www/jc/static/security.txt"
|
|
||||||
Alias "/llms.txt" "/var/www/jc/static/llms.txt"
|
|
||||||
|
|
||||||
|
|
||||||
<Files jc.wsgi>
|
<Files jc.wsgi>
|
||||||
Require all granted
|
Require all granted
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@ set -x -o pipefail
|
|||||||
|
|
||||||
content_dir=""
|
content_dir=""
|
||||||
if [[ -d "../jc-content" ]]; then
|
if [[ -d "../jc-content" ]]; then
|
||||||
content_dir="-v $(realpath ../jc-content):/var/www/jc/projects:z"
|
content_dir="-v $(realpath ../jc-content):/var/www/jc/projects"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker run -e DISCORD_ERR_HOOK=dummy $1 $content_dir jc-ng-localtest
|
docker run -e DISCORD_ERR_HOOK=dummy $1 -v $(pwd)/src/:/var/www/jc $content_dir jc-ng-localtest
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from .content import ContentArea
|
|||||||
from .contact import ContactForm
|
from .contact import ContactForm
|
||||||
from .storage import LocalStorage
|
from .storage import LocalStorage
|
||||||
from .links import Links
|
from .links import Links
|
||||||
|
from .comments import *
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ projects = ContentArea(
|
|||||||
app.register_blueprint(projects, url_prefix='/projects')
|
app.register_blueprint(projects, url_prefix='/projects')
|
||||||
app.register_blueprint(ContactForm('contact', __name__), url_prefix='/contact')
|
app.register_blueprint(ContactForm('contact', __name__), url_prefix='/contact')
|
||||||
app.register_blueprint(Links(path.join(md_path, 'links.json'), 'links', __name__), url_prefix='/links')
|
app.register_blueprint(Links(path.join(md_path, 'links.json'), 'links', __name__), url_prefix='/links')
|
||||||
|
app.register_blueprint(Approval(path.join(projects.md_directory.uri, 'comments.db'), 'comments', __name__), url_prefix='/comments')
|
||||||
|
|
||||||
class DiscordLogger(logging.Handler):
|
class DiscordLogger(logging.Handler):
|
||||||
''' Simple logging handler to send a message to Discord '''
|
''' Simple logging handler to send a message to Discord '''
|
||||||
@@ -72,7 +74,7 @@ def inject_branding() -> dict:
|
|||||||
case _:
|
case _:
|
||||||
brand = req_domain
|
brand = req_domain
|
||||||
|
|
||||||
return {'branding': brand, 'url': req_domain}
|
return {'branding': brand}
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index() -> str:
|
def index() -> str:
|
||||||
@@ -140,7 +142,7 @@ def sitemap():
|
|||||||
url = ET.SubElement(root, 'url')
|
url = ET.SubElement(root, 'url')
|
||||||
ET.SubElement(url, 'loc').text = base_url + route
|
ET.SubElement(url, 'loc').text = base_url + route
|
||||||
ET.SubElement(url, 'lastmod').text = date
|
ET.SubElement(url, 'lastmod').text = date
|
||||||
for article in projects.get_all_posts():
|
for article in projects.get_live_posts():
|
||||||
if 'link' in article.metadata:
|
if 'link' in article.metadata:
|
||||||
continue
|
continue
|
||||||
url = ET.SubElement(root, 'url')
|
url = ET.SubElement(root, 'url')
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
from flask import Blueprint, Response, request
|
||||||
|
from uuid import uuid4
|
||||||
|
from requests import post
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
|
||||||
|
class PostComments():
|
||||||
|
def __init__(self, post_id: str, db_path: str):
|
||||||
|
self.__db_path = db_path
|
||||||
|
self.__post_id = post_id
|
||||||
|
self._webhook = environ['DISCORD_WEBHOOK']
|
||||||
|
with sqlite3.connect(db_path) as db:
|
||||||
|
cursor = db.cursor()
|
||||||
|
cursor.execute("CREATE TABLE IF NOT EXISTS comments (name TEXT, comment TEXT, date INT, post_id TEXT, approved BOOL, key TEXT)")
|
||||||
|
self.comments = cursor.execute(
|
||||||
|
"SELECT name, comment, date FROM comments WHERE approved = 1 AND post_id = ? ORDER BY date DESC",
|
||||||
|
(post_id,)
|
||||||
|
).fetchall()
|
||||||
|
|
||||||
|
def send_to_discord(self, name: str, comment: str, comment_id: int, key: str):
|
||||||
|
''' Send the message '''
|
||||||
|
message_to_send = f'New comment from {name}\n\n{comment}'
|
||||||
|
if len(message_to_send) > 2000:
|
||||||
|
chars_to_lose = len(message_to_send) - 1900
|
||||||
|
message_to_send = message_to_send[-chars_to_lose:]
|
||||||
|
message_to_send += f'\n\n[Approve](https://jakecharman.co.uk/comments/approve/{comment_id}?key={key})'
|
||||||
|
post(self._webhook, data={'content': message_to_send}, timeout=30)
|
||||||
|
|
||||||
|
def make_comment(self, name: str, comment: str):
|
||||||
|
with sqlite3.connect(self.__db_path) as db:
|
||||||
|
key = str(uuid4())
|
||||||
|
cursor = db.cursor()
|
||||||
|
cursor.execute(
|
||||||
|
"INSERT INTO comments (name, comment, date, post_id, approved, key) VALUES (?, ?, datetime('now'), ?, 0, ?)",
|
||||||
|
(name, comment, self.__post_id, key)
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
|
self.send_to_discord(name, comment, cursor.lastrowid, key)
|
||||||
|
return cursor.lastrowid
|
||||||
|
|
||||||
|
class Approval(Blueprint):
|
||||||
|
def __init__(self, db_path: str, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.__db_path = db_path
|
||||||
|
self.add_url_rule('/approve/<comment_id>', view_func=self.approve)
|
||||||
|
|
||||||
|
def approve(self, comment_id: str):
|
||||||
|
with sqlite3.connect(self.__db_path) as db:
|
||||||
|
cursor = db.cursor()
|
||||||
|
key = cursor.execute("SELECT key FROM comments WHERE rowid = ?", (comment_id,)).fetchone()[0]
|
||||||
|
if request.args.get('key') == key:
|
||||||
|
with sqlite3.connect(self.__db_path) as db:
|
||||||
|
cursor = db.cursor()
|
||||||
|
cursor.execute("UPDATE comments SET approved = 1 WHERE rowid = ?", (comment_id,))
|
||||||
|
db.commit()
|
||||||
|
return Response(status=200)
|
||||||
|
return Response(status=403)
|
||||||
@@ -6,8 +6,9 @@ from datetime import datetime
|
|||||||
import frontmatter
|
import frontmatter
|
||||||
from markdown import markdown
|
from markdown import markdown
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from flask import render_template, Response, Blueprint
|
from flask import render_template, Response, Blueprint, request, redirect
|
||||||
from .storage import LocalStorage
|
from .storage import LocalStorage
|
||||||
|
from .comments import PostComments, Approval
|
||||||
|
|
||||||
class ContentArea(Blueprint):
|
class ContentArea(Blueprint):
|
||||||
def __init__(self, directory: LocalStorage, *args, **kwargs):
|
def __init__(self, directory: LocalStorage, *args, **kwargs):
|
||||||
@@ -24,7 +25,7 @@ class ContentArea(Blueprint):
|
|||||||
self.add_url_rule('/', view_func=self.projects)
|
self.add_url_rule('/', view_func=self.projects)
|
||||||
self.add_url_rule('/category/<category_id>/', view_func=self.category)
|
self.add_url_rule('/category/<category_id>/', view_func=self.category)
|
||||||
self.add_url_rule('/<article_id>', view_func=self.article)
|
self.add_url_rule('/<article_id>', view_func=self.article)
|
||||||
#self.add_url_rule('/image/<image_name>', view_func=self.image)
|
self.add_url_rule('/<article_id>/comment', view_func=self.comment, methods=['POST'])
|
||||||
|
|
||||||
def processor(self) -> dict:
|
def processor(self) -> dict:
|
||||||
''' Jninja processors '''
|
''' Jninja processors '''
|
||||||
@@ -140,6 +141,16 @@ class ContentArea(Blueprint):
|
|||||||
return Response(status=500)
|
return Response(status=500)
|
||||||
|
|
||||||
the_article = articles[0]
|
the_article = articles[0]
|
||||||
|
|
||||||
|
comments = PostComments(the_article.metadata['id'], path.join(self.md_directory.uri, 'comments.db')).comments
|
||||||
return render_template('article.html', post=markdown(the_article.content),
|
return render_template('article.html', post=markdown(the_article.content),
|
||||||
metadata=the_article.metadata,
|
metadata=the_article.metadata,
|
||||||
page_title=f'{the_article.metadata["title"]} - ')
|
comments = comments,
|
||||||
|
page_title=f'{the_article.metadata["title"]} - ')
|
||||||
|
|
||||||
|
def comment(self, article_id: str):
|
||||||
|
PostComments(article_id, path.join(self.md_directory.uri, 'comments.db')).make_comment(
|
||||||
|
request.form['name'],
|
||||||
|
request.form['comment']
|
||||||
|
)
|
||||||
|
return redirect(f'/projects/{article_id}?comment=true#comments')
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends 'main.html' %}
|
{% extends 'main.html' %}
|
||||||
{% block description %}{{ metadata.description }}{% endblock %}
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% if metadata.gallery %}
|
{% if metadata.gallery %}
|
||||||
<script>
|
<script>
|
||||||
@@ -11,31 +11,6 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "BlogPosting",
|
|
||||||
"headline": {{ metadata.title | tojson }},
|
|
||||||
"datePublished": "{{ metadata.date }}",
|
|
||||||
"image": "https://{{ url }}/image/{{ metadata.image }}",
|
|
||||||
"author": {
|
|
||||||
"@type": "Person",
|
|
||||||
"name": "Jake Charman",
|
|
||||||
"url": "https://{{ url }}/"
|
|
||||||
},
|
|
||||||
"mainEntityOfPage": "https://{{ url }}/projects/{{ metadata.id }}"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "BreadcrumbList",
|
|
||||||
"itemListElement": [
|
|
||||||
{"@type": "ListItem", "position": 1, "name": "Projects", "item": "https://{{url}}/projects/"},
|
|
||||||
{"@type": "ListItem", "position": 2, "name": {{ metadata.title | tojson }}, "item": "https://{{url}}/projects/{{ metadata.id }}"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@@ -47,4 +22,23 @@
|
|||||||
{{post|safe}}
|
{{post|safe}}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
<section id="comments">
|
||||||
|
<h2>{{comments | length}} Comment{% if comments | length != 1 %}s{% endif %}</h2>
|
||||||
|
{% for comment in comments %}
|
||||||
|
<div class="comment">
|
||||||
|
<strong>{{ comment[0] }} - {{ comment[2] | human_date }}</strong>
|
||||||
|
<p>{{ comment[1] }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<h3>Leave a comment</h3>
|
||||||
|
{% if request.args.get('comment') is none %}
|
||||||
|
<form action="./{{metadata.id}}/comment" method="post">
|
||||||
|
<input type="text", name="name" placeholder="Name" required>
|
||||||
|
<textarea name="comment" placeholder="Comment" required></textarea>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<p>Thank you! Your comment will appear once it is approved</p>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
{% extends 'main.html' %}
|
{% extends 'main.html' %}
|
||||||
|
|
||||||
{% block logo %}<a href='/'><h1>{{branding|upper}}</h1></a>{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main>
|
<main>
|
||||||
<section id="technology">
|
<section id="technology">
|
||||||
@@ -20,31 +18,31 @@
|
|||||||
My personal projects can also be found over on the <a href="/projects/">projects</a> page. Be aware though that if I'm able to write about a project here, it most likely wasn't done professionally so some may be a little rough around the edges.
|
My personal projects can also be found over on the <a href="/projects/">projects</a> page. Be aware though that if I'm able to write about a project here, it most likely wasn't done professionally so some may be a little rough around the edges.
|
||||||
</p>
|
</p>
|
||||||
<div id="techlogos">
|
<div id="techlogos">
|
||||||
<a href="https://ansible.com"><img alt="Ansible Logo" src="/static/images/technology/ansible.png" /></a>
|
<a href="https://ansible.com"><img src="/static/images/technology/ansible.png" /></a>
|
||||||
<a href="https://aws.amazon.com/"><img alt="AWS Logo" src="/static/images/technology/aws.png" /></a>
|
<a href="https://aws.amazon.com/"><img src="/static/images/technology/aws.png" /></a>
|
||||||
<a href="https://azure.microsoft.com/en-gb"><img alt="Azure Logo" src="/static/images/technology/azure.png" /></a>
|
<a href="https://azure.microsoft.com/en-gb"><img src="/static/images/technology/azure.png" /></a>
|
||||||
<a href="https://dotnet.microsoft.com/en-us/languages/csharp"><img alt="C# Logo" src="/static/images/technology/csharp.png" /></a>
|
<a href="https://dotnet.microsoft.com/en-us/languages/csharp"><img src="/static/images/technology/csharp.png" /></a>
|
||||||
<a href="https://www.debian.org/"><img alt="Debian Logo" src="/static/images/technology/debian.png" /></a>
|
<a href="https://www.debian.org/"><img src="/static/images/technology/debian.png" /></a>
|
||||||
<a href="https://www.digitalocean.com/"><img alt="DigitalOcean Logo" src="/static/images/technology/digitalocean.png" /></a>
|
<a href="https://www.digitalocean.com/"><img src="/static/images/technology/digitalocean.png" /></a>
|
||||||
<a href="https://www.docker.com/"><img alt="Docker Logo" src="/static/images/technology/docker.png" /></a>
|
<a href="https://www.docker.com/"><img src="/static/images/technology/docker.png" /></a>
|
||||||
<a href="https://www.freeipa.org/"><img alt="FreeIPA Logo" src="/static/images/technology/freeipa.png" /></a>
|
<a href="https://www.freeipa.org/"><img src="/static/images/technology/freeipa.png" /></a>
|
||||||
<a href="https://cloud.google.com/"><img alt="Google Cloud Logo" src="/static/images/technology/gcloud.png" /></a>
|
<a href="https://cloud.google.com/"><img src="/static/images/technology/gcloud.png" /></a>
|
||||||
<a href="https://git-scm.com/"><img alt="Git Logo" src="/static/images/technology/git.png" /></a>
|
<a href="https://git-scm.com/"><img src="/static/images/technology/git.png" /></a>
|
||||||
<a href="https://www.grafana.com/"><img alt="Grafana Logo" src="/static/images/technology/grafana.png" /></a>
|
<a href="https://www.grafana.com/"><img src="/static/images/technology/grafana.png" /></a>
|
||||||
<a href="https://hadoop.apache.org/"><img alt="Hadoop Logo" src="/static/images/technology/hadoop.svg" /></a>
|
<a href="https://hadoop.apache.org/"><img src="/static/images/technology/hadoop.svg" /></a>
|
||||||
<a href="https://hive.apache.org/"><img alt="Hive Logo" src="/static/images/technology/hive.svg" /></a>
|
<a href="https://hive.apache.org/"><img src="/static/images/technology/hive.svg" /></a>
|
||||||
<a href="https://www.java.com/"><img alt="Java Logo" src="/static/images/technology/java.png" /></a>
|
<a href="https://www.java.com/"><img src="/static/images/technology/java.png" /></a>
|
||||||
<a href="https://www.jenkins.io/"><img alt="Jenkins Logo" src="/static/images/technology/jenkins.png" /></a>
|
<a href="https://www.jenkins.io/"><img src="/static/images/technology/jenkins.png" /></a>
|
||||||
<a href="https://mariadb.org/"><img alt="MariaDB Logo" src="/static/images/technology/mariadb.png" /></a>
|
<a href="https://mariadb.org/"><img src="/static/images/technology/mariadb.png" /></a>
|
||||||
<a href="https://nginx.org/"><img alt="NGINX Logo" src="/static/images/technology/nginx.svg" /></a>
|
<a href="https://nginx.org/"><img src="/static/images/technology/nginx.svg" /></a>
|
||||||
<a href="https://www.proxmox.com/"><img alt="Proxmox Logo" src="/static/images/technology/proxmox.png" /></a>
|
<a href="https://www.proxmox.com/"><img src="/static/images/technology/proxmox.png" /></a>
|
||||||
<a href="https://www.python.org/"><img alt="Python Logo" src="/static/images/technology/python.png" /></a>
|
<a href="https://www.python.org/"><img src="/static/images/technology/python.png" /></a>
|
||||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img alt="RedHat Logo" src="/static/images/technology/redhat.png" /></a>
|
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="/static/images/technology/redhat.png" /></a>
|
||||||
<a href="https://rockylinux.org/"><img alt="Rocky Linux Logo" src="/static/images/technology/rocky.png" /></a>
|
<a href="https://rockylinux.org/"><img src="/static/images/technology/rocky.png" /></a>
|
||||||
<a href="https://subversion.apache.org/"><img alt="Subversion Logo" src="/static/images/technology/svn.svg" /></a>
|
<a href="https://subversion.apache.org/"><img src="/static/images/technology/svn.svg" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div id="certs">
|
<div id="certs">
|
||||||
<a href="https://catalog-education.oracle.com/ords/certview/sharebadge?id=A6C9B3D3D21627EB9C2504395194FAF772E01412911D4ADC78063133D54579ED"><img alt="Oracle Cloud certification badge" src="/static/images/certs/OCIF2023CA.png" /></a>
|
<a href="https://catalog-education.oracle.com/ords/certview/sharebadge?id=A6C9B3D3D21627EB9C2504395194FAF772E01412911D4ADC78063133D54579ED"><img src="/static/images/certs/OCIF2023CA.png" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="social">
|
<div class="social">
|
||||||
<a class="button" href="https://www.linkedin.com/in/jakecharman/"><i class="fa-brands fa-linkedin-in"></i></a>
|
<a class="button" href="https://www.linkedin.com/in/jakecharman/"><i class="fa-brands fa-linkedin-in"></i></a>
|
||||||
@@ -66,7 +64,7 @@
|
|||||||
<p>I've also had the opportunity to work on a 10,000 horsepower Top Fuel Dragster. I <a href="https://jakecharman.co.uk/projects/topfuel_dragster">wrote about this on the Nitro Junkie website, and later extended that post here.</a></p>
|
<p>I've also had the opportunity to work on a 10,000 horsepower Top Fuel Dragster. I <a href="https://jakecharman.co.uk/projects/topfuel_dragster">wrote about this on the Nitro Junkie website, and later extended that post here.</a></p>
|
||||||
<div class="gallery">
|
<div class="gallery">
|
||||||
<iframe class="yt" src="https://www.youtube.com/embed/Wa-V8mQTXFk?si=W-LzfR3Qj_jgAdkY&clip=UgkxV9lBj4pP1cvnR5seb82RQpWeE7RdnOXB&clipt=EOrWtgsYyqu6Cw&autoplay=1&mute=1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
<iframe class="yt" src="https://www.youtube.com/embed/Wa-V8mQTXFk?si=W-LzfR3Qj_jgAdkY&clip=UgkxV9lBj4pP1cvnR5seb82RQpWeE7RdnOXB&clipt=EOrWtgsYyqu6Cw&autoplay=1&mute=1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||||
<img alt="Jake working on a Top Fuel Dragster in the pits at Santa Pod Raceway" src="/static/images/jake_tf_1.jpg">
|
<img src="/static/images/jake_tf_1.jpg">
|
||||||
</div>
|
</div>
|
||||||
<div class="social">
|
<div class="social">
|
||||||
<a class="button" href="https://nitrojunkie.uk"><i class="fa-solid fa-globe"></i></a>
|
<a class="button" href="https://nitrojunkie.uk"><i class="fa-solid fa-globe"></i></a>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
{% if link.get('img') is not none %}
|
{% if link.get('img') is not none %}
|
||||||
<a href="{{link.src}}" target="_blank"></a>
|
<a href="{{link.src}}" target="_blank"></a>
|
||||||
<img class="link-thumb"
|
<img class="link-thumb"
|
||||||
alt="{{ link.title }}"
|
|
||||||
srcset="
|
srcset="
|
||||||
{% for i in range(200, 5100, 100) %}
|
{% for i in range(200, 5100, 100) %}
|
||||||
/image/{{ link.img }}?w={{i}} {{i}}w{{"," if not loop.last}}
|
/image/{{ link.img }}?w={{i}} {{i}}w{{"," if not loop.last}}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="{% block description %}Personal website of Jake Charman. A technology professional based in the UK.{% endblock %}">
|
<meta name="description" content="Personal website of Jake Charman. A technology professional based in the UK.">
|
||||||
<title>{{ page_title }}{{branding}}</title>
|
<title>{{ page_title }}{{branding}}</title>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&family=Tourney:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&family=Tourney:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Orbitron:[email protected]&family=Tourney:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Orbitron:[email protected]&family=Tourney:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||||
@@ -31,27 +31,6 @@
|
|||||||
|
|
||||||
gtag('config', 'G-6WMXXY0RL0');
|
gtag('config', 'G-6WMXXY0RL0');
|
||||||
</script>
|
</script>
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "Person",
|
|
||||||
"name": "Jake Charman",
|
|
||||||
"url": "https://jakecharman.co.uk/",
|
|
||||||
"jobTitle": "Technology Professional",
|
|
||||||
"sameAs": [
|
|
||||||
"https://www.linkedin.com/in/jakecharman/",
|
|
||||||
"https://github.com/jcharman/"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "WebSite",
|
|
||||||
"name": "{{ branding }}",
|
|
||||||
"url": "https://{{ url }}/"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -64,7 +43,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<div id="logo-container">
|
<div id="logo-container">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
{% block logo %}<a href='/'>{{branding|upper}}</a>{% endblock %}
|
<a href='/'><h1>{{branding|upper}}</h1></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
<a href="/projects/{{ row.id }}">
|
<a href="/projects/{{ row.id }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<img class="project-thumb"
|
<img class="project-thumb"
|
||||||
alt="{{ row.alt }}"
|
|
||||||
srcset="
|
srcset="
|
||||||
{% for i in range(200, 5100, 100) %}
|
{% for i in range(200, 5100, 100) %}
|
||||||
/image/{{ row.image }}?w={{i}} {{i}}w{{"," if not loop.last}}
|
/image/{{ row.image }}?w={{i}} {{i}}w{{"," if not loop.last}}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
# Jake Charman
|
|
||||||
|
|
||||||
> Personal website of Jake Charman, a technology professional based in the UK,
|
|
||||||
> covering distributed systems work and motorsport (Nitro Junkie Top Fuel drag racing).
|
|
||||||
|
|
||||||
## Pages
|
|
||||||
- [About](https://jakecharman.co.uk/): Background, technology stack, and motorsport involvement.
|
|
||||||
- [Projects](https://jakecharman.co.uk/projects/): Write-ups of personal and professional projects.
|
|
||||||
- [Links](https://jakecharman.co.uk/links/): Curated external links.
|
|
||||||
- [Contact](https://jakecharman.co.uk/contact/): Contact form.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Contact: mailto:[email protected]
|
|
||||||
Expires: 2036-01-01T00:00:00.000Z
|
|
||||||
Preferred-Languages: en
|
|
||||||
@@ -99,7 +99,6 @@
|
|||||||
.yt {
|
.yt {
|
||||||
width: calc(66% - 40px);
|
width: calc(66% - 40px);
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
height: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery {
|
.gallery {
|
||||||
|
|||||||
@@ -45,16 +45,7 @@ footer{
|
|||||||
|
|
||||||
#logo>a{
|
#logo>a{
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-family: "Orbitron", sans-serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
}
|
||||||
#logo>a>h1{
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
footer h2, section h2{
|
footer h2, section h2{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -337,4 +328,15 @@ pre{
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
height: 31vw;
|
height: 31vw;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
#comments {
|
||||||
|
border-top: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
background-color: #4c4c4c;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user