Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/oliverjam/oliverjames-v4
My place on the web
https://github.com/oliverjam/oliverjames-v4
Last synced: about 6 hours ago
JSON representation
My place on the web
- Host: GitHub
- URL: https://github.com/oliverjam/oliverjames-v4
- Owner: oliverjam
- Created: 2022-11-15T17:48:50.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-11T22:09:56.000Z (2 months ago)
- Last Synced: 2024-09-12T08:27:37.845Z (2 months ago)
- Language: JavaScript
- Homepage: https://oliverjam.es
- Size: 729 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# My place on the web
This is my personal website, [oliverjam.es](https://oliverjam.es). It's where I experiment with some fun stuff and write blog posts. It is almost certainly over-engineered for the task of turning Markdown into HTML, since I wrote almost all the code from scratch. Currently (other than the Deno standard library) it has 3 external dependencies: `marked`, `yaml` and `prismjs`. I have no interest in writing a Markdown parser from scratch.
## Docs
The below documentation is mostly so I don't forget how everything works.
### Local development
1. Make sure you have Git and Deno installed
1. Clone this repo and `cd` into the directory
1. Run `deno task dev` to generate the `_site/` directory
1. In another terminal tab run `deno task serve` to serve the site### Deploying
The `deploy.sh` script is a self-contained way to install Deno and build the site into `_site/`. This is currently run on Cloudflare Pages, but could easily be used on Netlify or in a GitHub Action or something. You just need to configure the platform to serve the `_site/` directory after building.
### Creating pages
Any `.jsx` file in the `pages/` directory will be generated as an HTML page. The default export of the module should be a function that returns JSX. This JSX will be the content of the generated HTML file. The final HTML path matches the page file path. For example `pages/index.jsx`:
```jsx
export default () =>Home
;
```will generate `_site/index.html`:
```html
Home
```The page module can export a `url` variable to override the final path. For example `pages/feed.jsx`:
```jsx
export let url = "feed.xml";
export default () => ...;
```will generate `_site/feed.xml`.
#### Multiple pages from one template
A page module can generate many HTML pages by returning an _array_ from its default export. Each array item should be an object with `url` and `component` properties. Each item will generate its own HTML page. For example:
```jsx
export default () => {
return [1, 2, 3].map((num) => ({
url: num + ".html",
component:{num}
,
}));
};
```will generate `_site/1.html` containing `
1
`, `_site/2.html` containing `2
`, and `_site/3.html` containing `3
`.To make this more obvious I have prefixed files that generate multiple pages with a `$`. E.g. `pages/$article.jsx` generates all the article pages.
### Content
`lib/data.js` reads all the markdown files in `content/` and parses the content to metadata + HTML. It also reads all CSS files in `styles/` so pages can inline the correct styles. Pages can import these—module caching means it should only run once per build.
#### Markdown
All `content/` files are rendered with the renderer in `lib/markdown.js`, which uses the `marked` parser. Headings have links and IDs added so they can be linked to, and code blocks are syntax highlighted using `prismjs`. Metadata is extracted from frontmatter and parsed using the `yaml` parser.
### Assets
Each file in `/assets` is copied through to `_site/assets` with a hash of its contents added to its filename. E.g. `assets/me.jpg -> _site/me.f5fd402f.jpg`. This ensures the path will change if the file contents do, allowing us to cache these files forever in the browser.
Components can import a map of original file names to final hashed paths, since they otherwise cannot know the true path. For example:
```jsx
import { ASSETS } from "../lib/assets.js"function Avatar {
return
}
```### Dev server
There is a minimal streaming static file server in `lib/serve.js` for use in development. This expects to be passed a directory to serve and will attempt to resolve HTTP requests to files in that directory. If it encounters an error it will attempt to serve `404.html` or `500.html` files (for missing file or general errors respectively), to match how Cloudflare Pages handles errors in production.
### JSX
There is a minimal JSX runtime in `lib/jsx`. Deno is configured to use this via the `compilerOptions` in `deno.json` and the import map in `import-map.json`. The renderer in `lib/jsx/render.js` attempts to recursively render JSX objects to HTML strings, with support for things like boolean attributes and void elements.