* added contact page and updated links

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* Feature/blog (#22)

* updated blogpost component

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* added first post and template post

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* updated styles

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* tweaked stuff

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* added custom header components

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* updated scss

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* added placeholder for future reference

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* tweaked around styles a bit :3

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* added basic search to blogposts

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* added pdading to md

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* fixed css issue

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

* tweaked css to make links more visible for blogposts

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

---------

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>

---------

Signed-off-by: Ash Entwisle <ash.entwisle@protonmail.com>
pull/4/head
Ash 2024-02-26 14:13:09 +00:00 committed by GitHub
parent 2e00275c90
commit d002a6e808
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 690 additions and 86 deletions

View File

@ -1,16 +1,235 @@
---
import Todo from "./Todo.astro";
import Markdown from "./Markdown.astro";
import Error from "./Error.astro";
import Icon from "../components/base/Icon.astro";
const { frontmatter } = Astro.props;
const props = Astro.props;
// if frontmatter.link is not defined, use the current url as the author's link
props.frontmatter.link = props.frontmatter.link || Astro.url;
// get the last part of the url
const url = Astro.url.pathname.split("/").pop();
const headings = Astro.props.headings || [];
// if draft, it will 404
if (frontmatter.draft) {
return Astro.redirect('/404');
}
---
<Markdown frontmatter={frontmatter}>
<slot />
</Markdown>
{
props.frontmatter.draft ?
<Error code="501" title="Draft">
Sorry, the page `<code>{Astro.url}</code>` is in draft mode.
</Error>
:
<Markdown frontmatter={props.frontmatter}>
<div class="markdown_title">
<h1 class="md_title" id={`#${url}`}>
<span class="md_title_hash">#</span>
<span class="md_title_text">{props.frontmatter.title}</span>
<a href={`#${url}`} class="md_title_link">
<Icon icon={{code: "f0c1", bold: true}}/>
</a>
</h1>
<h2>
By: <a href={props.frontmatter.link}>@{props.frontmatter.author.replace(" ", "_").toLowerCase()}</a>
<em>({props.frontmatter.date})</em>
</h2>
<blockquote>{props.frontmatter.description}</blockquote>
</div>
<div class="markdown_toc">
{ /* TODO */ }
</div>
<div class="markdown_content">
<slot />
</div>
</Markdown>
}
<script>
// TODO: This code is cancer, but it works. ill fix it later^tm
// this only exists bc astro has made a breaking change and has not put it in there docs smh
// ill make a pr to fix the docs later^tm
const hashSpan = document.createElement("span");
hashSpan.textContent = "#";
hashSpan.className = "md_title_hash";
const mdIcon = document.createElement("i");
mdIcon.innerHTML = "&#xf0c1;";
mdIcon.className = "md_title_icon";
mdIcon.style.cursor = "pointer";
mdIcon.style.fontWeight = "900";
const h1s = document.querySelectorAll(".markdown_content h1");
const h2s = document.querySelectorAll(".markdown_content h2");
const h3s = document.querySelectorAll(".markdown_content h3");
const h4s = document.querySelectorAll(".markdown_content h4");
const h5s = document.querySelectorAll(".markdown_content h5");
const h6s = document.querySelectorAll(".markdown_content h6");
h1s.forEach(h1 => {
const id = h1.id;
const text = h1.textContent;
h1.className = "md_title";
h1.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "#";
spantest.className = "md_title_hash";
h1.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h1.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h1.appendChild(link);
});
h2s.forEach(h2 => {
const id = h2.id;
const text = h2.textContent;
h2.className = "md_title";
h2.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "##";
spantest.className = "md_title_hash";
h2.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h2.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h2.appendChild(link);
});
h3s.forEach(h3 => {
const id = h3.id;
const text = h3.textContent;
h3.className = "md_title";
h3.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "###";
spantest.className = "md_title_hash";
h3.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h3.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h3.appendChild(link);
});
h4s.forEach(h4 => {
const id = h4.id;
const text = h4.textContent;
h4.className = "md_title";
h4.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "####";
spantest.className = "md_title_hash";
h4.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h4.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h4.appendChild(link);
});
h5s.forEach(h5 => {
const id = h5.id;
const text = h5.textContent;
h5.className = "md_title";
h5.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "#####";
spantest.className = "md_title_hash";
h5.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h5.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h5.appendChild(link);
});
h6s.forEach(h6 => {
const id = h6.id;
const text = h6.textContent;
h6.className = "md_title";
h6.innerHTML = "";
const spantest = document.createElement("span");
spantest.textContent = "######";
spantest.className = "md_title_hash";
h6.appendChild(spantest);
const spantext = document.createElement("span");
spantext.textContent = text;
spantext.className = "md_title_text";
h6.appendChild(spantext);
const link = document.createElement("a");
link.href = `#${id}`;
link.className = "md_title_link";
link.appendChild(mdIcon.cloneNode(true));
h6.appendChild(link);
});
// for every h element that has md_link give them an onclick event to copy the link to the clipboard
const hElements = document.querySelectorAll(".md_title");
hElements.forEach(h => {
h.addEventListener("click", () => {
const a = h.querySelector("a");
const link = a!.href;
navigator.clipboard.writeText(link);
window.history.pushState({}, "", link);
});
});
</script>

View File

@ -1,4 +1,106 @@
---
import Todo from "../layouts/Todo.astro";
import Center from "../components/base/Center.astro";
import Icon from "../components/base/Icon.astro";
import Boilerplate from "../layouts/Boilerplate.astro";
const rawPosts = await Astro.glob("./posts/*.mdx");
const search = Astro.url.searchParams.get("q") || "";
const posts = rawPosts
.filter((post) => !post.frontmatter.draft)
.map((post) => {
return {
url: post.url ?? "/",
data: post.frontmatter,
}
});
const filteredPosts = posts.filter((post) => {
return post.data.title.toLowerCase()
.includes(search.toLowerCase())
||
post.data.description.toLowerCase()
.includes(search.toLowerCase());
});
const keywords = [
"hull",
"computer",
"science",
"society",
"hcss",
"hcssoc",
"hull",
"university",
"students",
"student",
"union",
"hull",
"css",
"society",
"computer",
];
---
<Todo />
<Boilerplate
title="Hull Computer Science Society"
description="This is the Hull Computer Science Society website."
keywords={keywords}
header={true}
footer={true}
>
<div id="blog_main">
<div class="blog_search">
<Center id="search">
<form action="/blog" method="get">
<input type="text" name="q" placeholder={search || "Search..."} value="" />
<button type="submit">
<Icon icon={{code: "f002", bold: true}}/>
</button>
</form>
</Center>
</div>
<div class="blog_posts">
{
filteredPosts.map((post) => (
<div class="blog_post" id={ post.url.split("/").pop() }>
<h2>
<span class="blog_post_hash">#</span>
<a href={post.url}>
<span class="blog_post_title">{post.data.title}</span>
{ /* <span class="blog_post_link"><Icon icon={{code: "f0c1", bold: true}}/></span> */ }
</a>
</h2>
<p>
{post.data.description}
</p>
<h3><em>
<span class="blog_post_author"> By: <a href={post.data.link}> @{post.data.author.replace(" ", "_").toLowerCase()}</a> </span>
<span class="blog_post_date"> ({post.data.date}) </span>
</em></h3>
</div>
))
}
</div>
</div>
</Boilerplate>
<script>
document.addEventListener("keydown", (e) => {
if (
e.key === "k" && (e.metaKey || e.ctrlKey) ||
e.key === "/"
) {
e.preventDefault();
document.querySelector("input")?.focus();
}
});
</script>

View File

@ -0,0 +1,65 @@
---
# Edit all of this
title: "New Website"
author: "Ash Entwisle"
link: "https://github.com/ash-entwisle"
date: "2024-02-23"
description: "
After about 6 months of work,
I'm Happy to announce the new HullCSS website is Live!!
So, im taking this as the perfect opportunity
to talk about the tools and technologies that went into making it.
"
draft: false
# DO NOT EDIT
layout: ../../layouts/Blogpost.astro
---
## The Framework
The website is built [#withastro](https://astro.build/),
a fairly new, simple and powerful framework that allows you to build frontend sites and client-side applications.
I chose this because it's super fast, and it's super easy to use
and I can use components written in other frameworks like react and svelte
allowing me to use components that I have already written in other projects.
### Components
Most components are written in Astro,
but when making more reactive components (like the text typing effect on the homepage),
I used [Svelte](https://svelte.dev/).
Astro makes it really easy to use components from other frameworks such as svelte and react.
### Blogposts
For the blogposts, I used the MDX library for Astro. It allows me to write posts in a markdown-like syntax
while givig me the ability to use components and other features that are not available in regular markdown.
### Styling
For styling, I mostly used Sass (more specifically SCSS) to style the website.
I chose this over other options bc its close enough to CSS that I can use it without much of a learning curve,
but it also has some great quality of life features that make css so much more bearable to use.
#### Theme
For the colours, I chose to use [OneDark](https://github.com/atom/one-dark-ui).
A theme originally created to be used with the Atom text editor,
but has since been ported to many other applications and tools.
I chose this because I love the colours and I think it looks great
(if you look at my github, youll see that a lot of my other projects use this theme too lol).
I have tweaked the colours a bit just to make the theme more flexible.
## Hosting prodivder
For hosting, I chose to use [CloudFlare Pages](https://pages.cloudflare.com/),
a serverless platform that allows you to build, host, and scale your website or web application on the edge.
I chose this because it's free (up to 250k reqs/day) and it's super easy to use.
It also has an integration with GitHub, so I can just push to my repo and it will automatically build and deploy my site for me.
## Suggestions and Feedback
If you have any questions, suggestions or feedback,
feel free to [open an issue](https://github.com/hullcss/hullcss-astro/issues) on the GitHub repo
or ping me *(`@sudo_rm_rf_msft`)* in the [HullCSS Discord](/links/discord).

View File

@ -1,15 +1,14 @@
---
# Edit all of this
# title: "Example Title"
# author: "Ash Entwisle"
# title: "Webmaster"
# date: "2023-01-31"
# description: "Example description"
# tags: ["Tag 1", "Tag 2", "..."]
# draft: true # set to false to publish
title: "Example Title"
author: "Your Name"
link: "https://github.com/ash-entwisle" # can be any link
date: "YYYY-MM-DD" # do not format this differently, it is used to sort the blogposts
description: "Example description"
draft: true # this should only be true if you are still working on the blogpost, once it is ready to be published, set this to false
# Don't edit this
# layout: ../layouts/Blogpost.astro
# DO NOT EDIT
layout: ../../layouts/Blogpost.astro
---
# This is an example Blogpost
@ -26,4 +25,4 @@ if someone tries to access a draft blogpost, they will get an unauthorised error
## Layout
DO NOT EDIT THE LAYOUT !!!!!!
***DO NOT EDIT THE LAYOUT !!!!!!***

View File

@ -13,23 +13,34 @@ main {
}
h1 {
font-size: 1.3em;
font-size: 1.5em;
font-weight: 600;
padding-bottom: 25px;
}
h2 {
font-size: 1.25em;
font-weight: 500;
font-size: 1.3em;
font-weight: 600;
padding-top: 20px;
padding-bottom: 10px;
}
h3 {
font-size: 1.15em;
font-weight: 500;
font-size: 1.2em;
font-weight: 600;
padding-top: 15px;
padding-bottom: 5px;
}
h4 {
font-size: 1.1em;
font-weight: 400;
font-weight: 500;
padding-top: 5px;
padding-bottom: 2.5px;
}
h5 {
@ -42,11 +53,6 @@ h6 {
font-weight: 400;
}
p {
font-size: 0.9em;
font-weight: 300;
}
a {
// font-size: 0.9em;
// font-weight: 300;
@ -77,8 +83,55 @@ a {
}
span {
font: inherit;
}
blockquote {
border-left: 2.5px solid $col-mono-5;
margin-top: 10px;
margin-bottom: 10px;
padding-left: 10px;
margin-left: 5px;
}
p {
font-size: 0.9em;
font-weight: 300;
em {
font-style: italic;
font-size: 0.9em;
font-weight: 300;
}
}
ul {
list-style-type: disc;
padding-left: 15px;
li {
font-size: 0.9em;
font-weight: 300;
}
}
ol {
list-style-type: decimal;
padding-left: 30px;
li {
font-size: 0.9em;
font-weight: 300;
}
}
i {
font-style: normal;
}
blockquote {

View File

@ -43,7 +43,7 @@ $col-dark-8: hsl(286, 67%, 58%);
// Foreground Colours
$col-fg-default: $col-mono-1;
$col-fg-muted: $col-mono-2;
$col-fg-subtle: $col-mono-2;
$col-fg-subtle: $col-mono-3;
$col-fg-onemph: $col-mono-1;
$col-fg-accent: $col-normal-4;

View File

@ -23,11 +23,13 @@ footer {
}
.info {
max-width: 375px;
max-width: 250px;
padding-right: 0;
}
.copywright {
padding-top: 0;
padding-right: 0;
span a {
font-size: 1em;
@ -38,11 +40,11 @@ footer {
.misc {
padding-top: 0;
padding-bottom: 0;
padding-right: 0;
}
div {
padding-left: 25px;
padding-right: 25px;
padding-right: 50px;
padding-top: 10px;
padding-bottom: 10px;
}

View File

@ -1,72 +1,116 @@
@import '../colours.scss';
markdown {
max-width: 700px;
main {
blockquote {
border-left: 2.5px solid $col-mono-5;
margin-top: 10px;
margin-bottom: 10px;
padding-left: 10px;
margin-left: 5px;
#error_main {
width: 100%;
}
h1 {
text-decoration: underline;
padding-top: 50px;
padding-bottom: 50px;
font-size: 1.5em;
padding-bottom: 5px;
}
h2 {
text-decoration: underline;
padding-top: 15px;
padding-bottom: 5px;
}
h3 {
text-decoration: underline;
.markdown_title {
padding-top: 10px;
padding-bottom: 5px;
}
padding-bottom: 25px;
p {
font-size: 0.9em;
font-weight: 300;
h1 {
font-size: 2em;
font-weight: 600;
text-decoration: none;
em {
font-style: italic;
padding-top: 0;
padding-bottom: 0;
font-size: 0.9em;
font-weight: 300;
span {
padding-right: 7.5px;
}
i {
padding-left: 2.5px;
font-size: 0.75em;
color: $col-bg-default;
transition: color 0.1s;
cursor: default;
}
&:hover {
i {
color: $col-fg-accent;
transition: color 0.1s;
cursor: pointer;
}
}
}
h2 {
font-size: 1em;
font-weight: 500;
text-decoration: none;
padding-top: 0;
padding-bottom: 0;
em {
padding-left: 5px;
font-size: 0.9em;
font-weight: 300;
}
}
p {
padding-top: 10px;
padding-bottom: 10px;
}
a {
text-decoration: none;
}
}
ul {
list-style-type: disc;
.md_title {
.md_title_hash {
color: $col-mono-4;
}
padding-left: 15px;
.md_title_text {
padding-left: 5px;
padding-right: 5px;
}
li {
font-size: 0.9em;
font-weight: 300;
.md_title_icon {
padding-left: 2.5px;
font-size: 0.75em;
color: $col-bg-default;
transition: color 0.1s;
}
a {
text-decoration: none;
cursor: default;
}
&:hover {
.md_title_icon {
color: $col-fg-accent;
transition: color 0.1s;
}
a {
// set cursor to pointer
cursor: pointer;
}
}
}
markdown {
ol {
list-style-type: decimal;
padding-left: 30px;
li {
font-size: 0.9em;
font-weight: 300;
}
max-width: 700px
}
}

View File

@ -20,6 +20,7 @@
@import 'pages/index.scss';
@import 'pages/404.scss';
@import 'pages/contact.scss';
@import 'pages/blog.scss';
// import fonts from ash's CDN
@import url('https://cdn.hullcss.org/styles/jb-mono.css');

115
src/styles/pages/blog.scss Normal file
View File

@ -0,0 +1,115 @@
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 0px;
#blog_main {
box-sizing: border-box;
padding: 2.5%;
max-width: 700px;
min-height: 60vh;
.blog_search {
form {
// make search bar darker than background
padding: 10px;
background-color: $col-bg-muted;
border: 2px;
border-radius: 5px;
input {
min-width: 175px;
// no border
border: 0px;
background-color: $col-bg-muted;
}
}
}
.blog_posts {
.blog_post {
h2 {
font-size: 1.5em;
font-weight: 600;
a {
text-decoration: none;
transition: 0.1s;
color: $col-fg-default;
transition: 0.1s;
}
i {
font-size: 0.8em;
font-weight: 300;
color: $col-bg-default;
transition: 0.1s;
}
.blog_post_title {
text-decoration: underline;
text-decoration-style: wavy;
color: $col-fg-accent;
}
.blog_post_hash {
color: $col-mono-4;
}
&:hover {
// i {
// color: $col-fg-accent;
// transition: 0.1s;
// }
// .blog_post_hash {
// color: $col-mono-4;
// transition: 0.1s;
// }
.blog_post_title {
// set underline to solid
text-decoration-style: solid;
transition: 0.1s;
}
}
}
h3 {
font-size: 0.8em;
font-weight: 300;
padding: 0;
padding-top: 5px;
}
&:hover {
h2 {
a {
color: $col-fg-accent;
transition: 0.1s;
i {
// TODO: fix css bug
color: $col-fg-default;
transition: 0.1s;
}
}
}
}
}
}
}
}

View File

@ -14,6 +14,8 @@ main {
h1 {
font-size: 1.5em;
font-weight: 600;
padding-bottom: 0px;
}
p {

View File

@ -21,7 +21,7 @@ main {
h1 span {
text-decoration: underline;
font-size: 1.75em;
font-size: 1.5em;
font-weight: 600;
}
@ -62,6 +62,8 @@ main {
margin: 0px;
margin-bottom: 10px;
padding: 0;
i {
font-weight: 300;
font-size: 0.9em;