Two decades ago I used to write my own web frameworks, later I mostly relied on WordPress for my needs. But WordPress has become somewhat bloated recently, with many people transitioning from the open, creative realm to seeking monetary compensation for their efforts. Although I understand this very well, it makes makes the infrastructure too cluttered for my taste. Thus, I decided to go for a static site generator (SSG) this time and I emotionally chose 11ty, for no conscious, rational reason.
With ChatGPT by my side, I decided to experiment with setting up a web page, including a blog, using just a Markdown editor on my personal computer and deploying it to a server.
So, we started, I asked ChatGPT:
Kaarel:
- I want you to act as the designer and developer of a simple web page for myself to inform the research community, colleagues and friends about my activities and interests and also have a blog to publish my more organised thoughts, give news and link to my social media (twitter and instagram). I am myself a researcher (...). I want the page to have following page structure:
(...)
Subpages should be available separately in the menu but implemented through seamless scrolling.
I want the web page to be solid and simple but with a gentle touch of Cyberpunk style artsyness, but mostly using the colour schema of Citroen C6 sable. I want my photo to also have a similar filter.
I want the web page to be created using 11ty static web generator which is connected to Google analytics and includes mermaid.js for generating visualisations. I want those charts to be generally styled with fine lines also by touch of the same colour scheme but still being able to use distinguishable colours in them, like blue and red.
How shall we continue with the site generation?
- To create the website based on your specifications, follow these steps:
- Set up the 11ty environment:
- Install Node.js and npm (https://nodejs.org/en/download/ )
- Create a new folder for your project
- Run
npm init -y
to create apackage.json
file - Install 11ty by running
npm install --save-dev @11ty/eleventy
- Add the following to your
package.json
file under "scripts":
"scripts": {
"start": "eleventy --serve",
"build": "eleventy"
}
- Create the required folders and files:
- Create the following folders:
_includes
,css
,images
, andposts
- Create an
index.html
file in the root directory - Create subpage HTML files:
about.html
,research.html
,cv.html
, andblog.html
- Create blog post files inside the
posts
folder:post1.html
,post2.html
- Set up your base layout in
_includes
:
- Create a
base.njk
file with the following structure:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta tags, title, and link to your CSS file -->
</head>
<body>
<header>
<!-- Navigation menu with links to subpages -->
</header>
<main>
</main>
<footer>
<!-- Footer content and links to social media -->
</footer>
</body>
</html>
- Create the content for each subpage:
- Use the
{% extends "base.njk" %}
and{% block content %}{% endblock %}
tags to inherit the base layout - Add the content for each subpage, including sections and subheadings
- Style your website:
- Create a
style.css
file in thecss
folder - Add the Citroen C6 sable color scheme and cyberpunk-inspired styling
- Apply a filter to your photo to match the color scheme
- Set up mermaid.js:
- Install mermaid via npm:
npm install mermaid
- Add mermaid to your
base.njk
file by adding the following line in the<head>
section:<script src="/node_modules/mermaid/dist/mermaid.min.js"></script>
- Configure mermaid in the
<head>
section by adding a script:
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'custom',
themeCSS: '/* Your custom CSS for mermaid charts */'
});
</script>
- Add mermaid diagrams in your CV and research pages by using the
mermaid
syntax
- Configure Google Analytics:
- Sign up for a Google Analytics account and create a new property for your website
- Get your tracking ID and add the following code to your
base.njk
file in the<head>
section:
<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR_TRACKING_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'YOUR_TRACKING_ID');
</script>
- Build and test your website:
- Run
Kaarel:
- Continue please
ChatGPT:
- Run
npm start
to start the development server
- Run
- Visit
http://localhost:8080
in your browser to view the website - Check that seamless scrolling works as expected and that the menu links navigate to the correct sections
- Review the layout, styling, and mermaid.js charts to ensure they match your requirements
- Optimize your website for performance and accessibility:
- Ensure all images are optimized for the web
- Use semantic HTML tags (e.g.,
\<header\>
,\<nav\>
,\<section\>
,\<article\>
,\<footer\>
) - Add appropriate
alt
attributes to images - Ensure proper heading hierarchy (e.g.,
\<h1\>
,\<h2\>
,\<h3\>
) - Check the website's responsiveness on various devices and screen sizes
- Deploy your website:
- Choose a hosting provider (e.g., GitHub Pages, Netlify, Vercel)
- Follow the hosting provider's instructions to deploy your 11ty website
- Configure your custom domain (if applicable)
- Ensure HTTPS is enabled for security
- Share your website with the research community, colleagues, and friends:
- Add the website link to your email signature, social media profiles, and academic profiles (e.g., Google Scholar, ResearchGate)
- Share your new website and blog posts on social media platforms
- Encourage colleagues and friends to visit your website and share their feedback
By following these steps, you should now have a solid, simple, and stylish website that showcases your research interests, CV, and blog. Make sure to regularly update your website with new blog posts and research updates to keep your audience engaged.
Good, that is a lot of instructions, but I see already a lot of those can be automated.
Thank you for this. I want to write the web page content not as .html but as .md files. Based on this can you create a bash script optimised for Ubuntu 22.04 for accomplishing your tasks 1 and 2
Kaarel:
- Thank you for this. I want to write the web page content not as .html but as .md files. Based on this can you create a bash script optimised for Ubuntu 22.04 for accomplishing your tasks 1 and 2
- Sure! I'll provide a bash script to set up the 11ty environment and create the required folders and files using Markdown format. Please make sure you have Node.js and npm installed before running the script.
#!/bin/bash
# Create a new folder for your project and navigate to it
mkdir my-website && cd my-website
# Initialize npm
npm init -y
# Install 11ty
npm install --save-dev @11ty/eleventy
# Update package.json with 11ty scripts
npx json -I -f package.json -e 'this.scripts={"start":"eleventy --serve","build":"eleventy"}'
# Create required folders
mkdir _includes css images posts
# Create index.md file in the root directory
echo '---
layout: base.njk
title: Home
---
# Welcome to my website' > index.md
# Create subpage Markdown files
echo '---
layout: base.njk
title: About
---
# About myself' > about.md
echo '---
layout: base.njk
title: Research
---
# Research
## Fieldworks
## Archaeological data science
## Socio-ecological systems
## Stone Age
## Control of ideas
## Relation between individual and a system
## Progression of humanity as an information processing system' > research.md
echo '---
layout: base.njk
title: CV
---
# CV
<!-- Insert your Mermaid.js Gantt chart here -->
## Classical CV
### Publications' > cv.md
echo '---
layout: base.njk
title: Blog
---
# Blog
- [Blog post 1](/posts/post1)
- [Blog post 2](/posts/post2)' > blog.md
# Create blog post files inside the posts folder
echo '---
layout: base.njk
title: Blog post 1
---
# Blog post 1
Content for blog post 1 goes here.' > posts/post1.md
echo '---
layout: base.njk
title: Blog post 2
---
# Blog post 2
Content for blog post 2 goes here.' > posts/post2.md
# Create base.njk layout file in _includes folder
echo '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/research">Research</a></li>
<li><a href="/cv">CV</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
</header>
<main>
{{ content | safe }}
</main>
<footer>
<!-- Footer content and links to social media -->
</footer>
</body>
</html>' > _includes/base.njk
echo "Setup complete! Run 'npm start' to start the development server."
To use this script:
- Save the script as
setup_website.sh
. - Open a terminal and navigate to the directory containing the script.
- Make the script executable by running
chmod +x setup_website.sh
. - Run the script with
./setup_website.sh
.
This script will create the necessary folders and files with
Alright, I am saving this the bash script, running it. Running the npm serve
and thats a wow moment, a web framework is up and running!!!
Kaarel:
- Could you please continue with step 4 creating an example content for each subpage and print out those file contents for me to copy and paste.
ChatGPT:
- Certainly! Here are the example content for each subpage in Markdown format. You can simply copy and paste the content into the respective
.md
files you created earlier.
about.md
:
---
layout: base.njk
title: About
---
# About myself
My name is [Your Name], and I am a researcher interested in archaeology, archaeological data science, simplex systems, cybernetics of natural systems, and modeling processes from the long-term human past as information processes. I also have significant experience in software development, including web development.
\![Your filtered photo](/images/your-photo.jpg)
You can find me on [Twitter](https://twitter.com/yourusername) and [Instagram](https://www.instagram.com/yourusername).
research.md
:
---
layout: base.njk
title: Research
---
# Research
## Fieldworks
(...)
# and so on
cv.md
:
---
layout: base.njk
title: CV
---
# CV
\```mermaid
gantt
dateFormat YYYY-MM-DD
title My CV
section Education
University A :a1, 2010-09-01, 2014-06-30
University B :a2, 2014-09-01, 2016-06-30
section Work Experience
Company X :b1, 2016-07-01, 2018-12-31
Company Y :b2, 2019-01-01, 2021-12-31
\```
## Classical CV
### Education
- B.A. in Archaeology, University A, 2010-2014
- M.A. in Archaeological Data Science, University B, 2014-2016
### Work Experience
- Software Developer, Company X, 2016-2018
- Researcher, Company Y, 2019-2021
### Publications
- [Publication 1](https://example.com/link-to-publication-1)
- [Publication 2](https://example.com/link-to-publication-2)
Make sure to remove the backslashes \
before the triple backticks when you paste the content into your cv.md
file.
blog.md
:
---
layout: base.njk
title: Blog
---
# Blog
- [Blog post 1](/posts/post1)
- [Blog post 2](/posts/post2)
Kaarel:
- Continue please
- Create a CSS file to style your website:
- In the
css
folder, create a new file namedstyle.css
. - Add the following basic styling to start:
/* CSS Reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
/* Basic styling */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f4f4f4;
}
/* Add your custom Cyberpunk-inspired styling and Citroen C6 sable color scheme here */
- Customize the website's appearance:
Update the
style.css
file with your desired Cyberpunk-inspired design and Citroen C6 sable color scheme.Apply the same filter to your photo as you want to use on the website. Save the edited photo in the
images
folder.Add your social media links to the footer in
base.njk
.Update the navigation links in
base.njk
to point to the section IDs you added inresearch.md
.
Kaarel:
- Lets go back for a second. How to do so that the Blog page automatically indexes and has all pages under posts/.md ordered by date and paginated by 10 titles and excerts for page?*
- To achieve this, you'll need to make some changes to your Eleventy configuration and update the
blog.md
file.
- Create an Eleventy configuration file:
- In your project's root directory, create a new file named
.eleventy.js
.
- Configure Eleventy to create a collection of all blog posts:
- Add the following code to the
.eleventy.js
file:
module.exports = function (eleventyConfig) {
// Create a collection of all blog posts
eleventyConfig.addCollection("posts", function (collectionApi) {
return collectionApi.getFilteredByGlob("posts/*.md").reverse();
});
};
- Update the
blog.md
file:
- Replace the existing content with the following code:
---
layout: base.njk
title: Blog
pagination:
data: collections.posts
size: 10
alias: posts
---
# Blog
- This code sets up pagination and creates a list of blog post titles with their excerpts (if available) and publication dates.
- Add excerpts to your blog posts:
- In each of your blog post Markdown files (e.g.,
posts/post1.md
andposts/post2.md
), add the following front matter variable with your desired excerpt:
excerpt: "An excerpt of the blog post goes here."
- Set up date formatting:
- Install the
date-fns
package:
npm install date-fns
- Update the
.eleventy.js
configuration file to use thedate-fns
package for date formatting:
const { format } = require("date-fns");
module.exports = function (eleventyConfig) {
// Create a collection of all blog posts
eleventyConfig.addCollection("posts", function (collectionApi) {
return collectionApi.getFilteredByGlob("posts/*.md").reverse();
});
// Add a filter for date formatting
eleventyConfig.addFilter("date", (date, dateFormat) => {
return format(date, dateFormat);
});
};
Now, the Blog page will automatically list all blog posts under the posts/
directory, ordered by date, with pagination set to display 10 titles and excerpts per page.
Kaarel:
- Thank you, that is incredible! But now I have another problem, css/style.css and images/image.jpg file seem to be not accessible currently, what to do?
ChatGPT:
- You might need to update the paths to your CSS and image files in your
base.njk
layout file to make sure they're accessible.
In your base.njk
file, ensure that the paths to your CSS and image files are correct. Since Eleventy uses the root directory as the base for file paths, you can use a leading slash (/
) for your static assets.
- Update the link to your
style.css
:
- Find the link to the
style.css
file in yourbase.njk
and update it as follows:
<link rel="stylesheet" href="/css/style.css" />
- Update the path to your image file:
- In your
about.md
file, make sure you have the correct path to your image file with a leading slash:
![Your filtered photo](/images/your-photo.jpg)
These changes should ensure that the paths to your CSS and image files are correct, and they should be accessible now.
If you're still having issues, you might need to check the browser's developer console for any error messages. This will help you understand if there are any issues with your file paths or any other errors that might be preventing the files from loading. To open the developer console, you can press F12
or Ctrl + Shift + I
(or Cmd + Option + I
on a Mac) in most browsers.
Kaarel:
- They are correct, but I have a feeling that eleventy requires some passthrough option to be added also in configuration?
- You're correct. Eleventy needs to be configured to copy your static assets (like the CSS and image files) to the
_site
folder during the build process. You can achieve this using theaddPassthroughCopy
method in your.eleventy.js
configuration file.
- Update your
.eleventy.js
file:
- Add the following lines to the
.eleventy.js
file to configure Eleventy to copy thecss
andimages
folders to the_site
folder:
module.exports = function (eleventyConfig) {
// Create a collection of all blog posts
eleventyConfig.addCollection("posts", function (collectionApi) {
return collectionApi.getFilteredByGlob("posts/*.md").reverse();
});
// Add a filter for date formatting
eleventyConfig.addFilter("date", (date, dateFormat) => {
return format(date, dateFormat);
});
// Copy the `css` and `images` folders to the output folder (`_site`)
eleventyConfig.addPassthroughCopy("css");
eleventyConfig.addPassthroughCopy("images");
};
- Rebuild your Eleventy site:
- Run the following command in your terminal to rebuild your site:
npx eleventy
After making these changes, Eleventy should copy the css
and images
folders to the _site
folder during the build process, and your CSS and image files should be accessible.
Kaarel:
Thank you. I now realise that the cyberpunk was misleading, you really did it very correctly. I'd like to have a very light, relaxed, full-of-space and fresh air C6 sable style, with light background for reading and gentle but clearly visible darker fonts on it. After this, lets reconsider the decorations
ChatGPT: CSS designSure! Let's update the styling for a more light and relaxed look with a Citroen C6 sable color scheme. Replace the existing CSS code in your
style.css
file with the following code:
:root {
--primary-color: #734222;
--secondary-color: #977648;
--accent-color: #b4c6cf;
--background-color: #f5f5f5;
--text-color: #444444;
}
body {
font-family: 'Roboto', sans-serif;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.5;
}
/* Header and Navigation */
header {
background-color: var(--primary-color);
padding: 20px;
position: relative;
overflow: hidden;
}
header::before {
content: "";
background-image: url("/images/header-decoration.svg");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.1;
z-index: -1;
}
nav {
text-align: center;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul li {
display: inline;
}
nav ul li a {
color: var(--text-color);
text-decoration: none;
padding: 0 10px;
transition: color 0.3s;
}
nav ul li a:hover {
color: var(--accent-color);
}
/* Footer */
footer {
background-color: var(--secondary-color);
padding: 20px;
position: relative;
overflow: hidden;
}
footer::before {
content: "";
background-image: url("/images/footer-decoration.svg");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.1;
z-index: -1;
}
footer p {
text-align: center;
margin: 0;
}
The updated styling uses a light background color for better readability and a gentle, darker font color.
For the decorations, (.. Ok asking ChatGPT for SVG decoration was too much, cutting it out ..)
Person:
- mermaid.js is still not initialised in base.njk could you send me the code please
Person:
Mermaid.js still does not work, I understand there might be a dedicated plugin for eleventy to initialise mermaid?
ChatGPT: Mermaid.js pluginYes, you're correct. There is a dedicated plugin for Eleventy to initialize Mermaid called
eleventy-plugin-mermaid
. To use this plugin, follow these steps:
- Install the plugin using npm:
npm install --save eleventy-plugin-mermaid
- In your
.eleventy.js
configuration file, require the plugin and add it to Eleventy:
const mermaidPlugin = require('eleventy-plugin-mermaid');
module.exports = function (eleventyConfig) {
// Add the mermaid plugin
eleventyConfig.addPlugin(mermaidPlugin);
// Your other configuration settings...
};
- Remove the script tags for Mermaid that you added to the
base.njk
file earlier, since the plugin will handle the loading and initialization of Mermaid for you. - In your Markdown file, wrap your Mermaid code with the
mermaid
shortcode provided by the plugin:
---
layout: base.njk
title: CV
---
## Gantt Chart
{% mermaid %}
gantt
dateFormat YYYY-MM-DD
title Kaarel Sikk's Timeline CV
section Education
University of XX MA :done, education, 2012-01-01, 2015-01-01
University of XX :done, education, 2017-01-01, 2022-01-01
section Career
AAA :done, work, 1997-01-01, 2000-01-01
BBB :done, work, 2000-01-01, 2001-01-01
section Projects and Events
AAA :done, project, 2012-01-01, 2014-01-01
Person:
- Let's go for styling and specifically for root color schema which I modified to: :root {
--accent-color: #b4c6cf;
--text-color: #444444;
--primary-color: #6e6d68;
--secondary-color: #b3b3b3;
--background-color: #f2f2f2;
}
Kaarel:
How can you add a separate body tag id to each page based on its url?
ChatGPT: Unique body idTo add a unique body ID based on the URL of each page, you can use the
page.url
property provided by Eleventy. In yourbase.njk
layout file, modify the<body>
tag like this:
<body id="bloghuman-ai-work-on-creation-of-this-web-page">
<!-- Your layout content -->
</body>
This code uses the slug
filter to create a URL-friendly string from the page.url
property. The result will be used as the body ID. The slug
filter comes built-in with Eleventy.
For example, if the URL of the current page is /about/
, the generated <body>
tag will look like this:
<body id="about">
<!-- Your layout content -->
</body>
This approach allows you to target specific pages in your CSS by using the body ID.
Kaarel:
How to use slugs in urls for blog posts?
ChatGPT: Slugs in urlsTo use slugs in URLs for your blog posts in Eleventy, follow these steps:
- Install the
slugify
package to create slugs from your blog post titles:
npm install slugify
- In your
.eleventy.js
configuration file, add a custom filter to convert titles into slugs using theslugify
package:
const slugify = require("slugify");
module.exports = (eleventyConfig) => {
// Add the custom slug filter
eleventyConfig.addFilter("slug", (input) => {
return slugify(input, {
lower: true,
remove: /[*+~.,()'"!:@]/g,
});
});
// Your other configuration settings
};
- In your
_data/posts.js
file, use the customslug
filter to create slugs for each post:
module.exports = (collection) => {
return collection
.getFilteredByGlob("posts/*.md")
.sort((a, b) => {
return b.date - a.date;
})
.map((post) => {
post.data.slug = post.data.title | slug; // Add the slug to the post data
return post;
});
};
- Update your
posts.json
pagination settings to use the slugs in URLs:
{
"pagination": {
"data": "posts",
"size": 10,
"alias": "posts",
"before": function(data) {
return data.slice(0, 10);
}
},
"permalink": "blog/human-ai-work-on-creation-of-this-web-page/"
}
Now, your blog posts will have URLs based on their slugs instead of the default format. This will create more readable and user-friendly URLs for your blog posts.
Person:
Could you please print out additional stylesheet section to create appropriate heading, division and lists formattin which suits current style
ChatGPT: Again CSSHere's an additional CSS snippet to enhance the heading, division, and list styles to suit your current theme. Add this to your existing
style.css
file:
h1, h2, h3, h4, h5, h6 {
color: var(--text-color);
font-weight: bold;
margin-top: 1em;
margin-bottom: 0.5em;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 2em;
}
h3 {
font-size: 1.75em;
}
h4 {
font-size: 1.5em;
}
h5 {
font-size: 1.25em;
}
h6 {
font-size: 1em;
}
p {
color: var(--text-color);
font-size: 1em;
line-height: 1.6;
margin-top: 0.5em;
margin-bottom: 1em;
}
ul, ol {
color: var(--text-color);
font-size: 1em;
line-height: 1.6;
margin-top: 0.5em;
margin-bottom: 1em;
padding-left: 1.25em;
}
ul li, ol li {
margin-bottom: 0.25em;
}
hr {
border: 1px solid var(--secondary-color);
margin-top: 1em;
margin-bottom: 1em;
}
This will provide consistent formatting for headings, paragraphs, lists, and horizontal rules while maintaining the color scheme and general style of your website.
Person:
- Can you give a nice design for links also by giving style for a tags, as in the menu they can slowlsy change color on mouseover
ChatGPT:
- Sure, here's a CSS snippet to style anchor tags (links) and add a smooth color transition effect on mouseover. Add this to your existing
style.css
file:
a {
color: var(--accent-color);
text-decoration: none;
transition: color 0.3s;
}
a:hover {
color: var(--primary-color);
transition: color 0.3s;
}
This will style the anchor tags with the accent color and smoothly change the color to the primary color on mouseover. The transition
property ensures that the color change happens gradually over 0.3 seconds, creating a smooth effect.
Person:
- --accent-color is too light can you propose a colorcode one which is harmony between elegeance, sable and the classic blue link?
ChatGPT:
- Certainly! Here's a color suggestion that combines elegance, the sable tone, and the classic blue link:
:root {
--link-color: #40738C;
}
a {
color: var(--link-color);
text-decoration: none;
transition: color 0.3s;
}
a:hover {
color: var(--primary-color);
transition: color 0.3s;
}
I've introduced a new variable --link-color
with a color value #40738C
. This color is a subtle blend of sable and classic blue, giving it an elegant touch. You can adjust the color value as needed to better match your desired aesthetics.
Person:
- What is the recent best practice to publish you email at web so that it is not going to be used for spam. Or is it not a problem recently?
ChatGPT:
- One of the best practices to prevent your email address from being used for spam is to avoid displaying it in plain text on your website. Instead, you can use the following methods:
- Email obfuscation: Obfuscate your email address by encoding it using JavaScript, so that it is more difficult for spammers to harvest your email. Here's an example:
<script>
document.write('<a href="mailto:' + 'yourname' + '@' + 'domain' + '.com">' + 'yourname' + '@' + 'domain' + '.com<\/a>');
</script>
- Contact form: Instead of displaying your email address, you can create a contact form on your website. This allows users to send you messages directly from the website without revealing your email address. There are many plugins and third-party services available to help you create a contact form.
- reCAPTCHA: If you use a contact form, consider adding Google's reCAPTCHA to prevent spam submissions. reCAPTCHA is a free service that helps protect your website from spam and abuse by requiring users to complete a simple challenge to prove they are human.
- Using an email alias: Another option is to use an email alias specifically for your website, which forwards messages to your main email address. This way, if the alias starts receiving too much spam, you can change it without affecting your primary email address.
While these methods are not foolproof, they can significantly reduce the chances of your email address being harvested for spam.
Person:
- In my about.md I have the following: ## Get in Touch
Email: kaarel.sikk@gmail.com
Can you write a code that completely obfuscates it in our constructed eleventy web page?
ChatGPT:
- Certainly! You can use the following JavaScript code to obfuscate your email address. Add this code snippet to your
about.md
file:
## Get in Touch
Email: <span id="email"></span>
<script>
var name = 'kaarel.sikk';
var domain = 'gmail.com';
var mailto = 'mailto:' + name + '@' + domain;
var linkText = name + '@' + domain;
document.getElementById('email').innerHTML = '<a href="' + mailto + '">' + linkText + '</a>';
</script>
This code will create an email link in your about.md
page. The JavaScript code constructs the email address and link dynamically, making it more difficult for spammers to harvest your email address.
Person:
- How to make links open in new tab?
ChatGPT:
- To make links open in a new tab, you can add the
target="_blank"
attribute to the<a>
tag. If you want to apply this to all the links in your content, you can use JavaScript.
First, add the following script to your base.njk
file, just before the closing </body>
tag:
<script>
document.addEventListener('DOMContentLoaded', function() {
var links = document.querySelectorAll('a');
for (var i = 0; i < links.length; i++) {
if (links[i].hostname !== window.location.hostname) {
links[i].target = '_blank';
links[i].rel = 'noopener noreferrer';
}
}
});
</script>
This script will add the target="_blank"
attribute to all external links, causing them to open in a new tab. It also adds the rel="noopener noreferrer"
attribute for security purposes, preventing the newly opened page from having access to the window.opener
object.
Person:
- In eleventy how to create inner urls in a way that Eg. http://localhost:8080/projects/#PaleoMIX just on projects page to project PaleoMIX ?
ChatGPT:
- In Eleventy, you can create inner URLs with anchor links. If you have a
projects.md
file or aprojects
folder with anindex.md
file inside, you can add an anchor link in your content to direct users to a specific section on the page.
First, add an ID to the section you want to link to in the projects.md
or projects/index.md
file:
## PaleoMIX Project {#PaleoMIX}
The {#PaleoMIX}
syntax will add an ID attribute to the generated HTML heading, like this:
<h2 id="PaleoMIX">PaleoMIX Project</h2>
Now, you can create a link to the PaleoMIX section using the following markdown syntax in any other file:
[Go to the PaleoMIX project](/projects/#PaleoMIX)
This will generate an HTML link that points to the PaleoMIX section on the projects page:
<a href="/projects/#PaleoMIX">Go to the PaleoMIX project</a>
When a user clicks on the link, they will be taken to the projects page, and the browser will automatically scroll to the PaleoMIX section.
Person:
- Before you wrote a code to obfuscate my email, could you give another simple one with uses two-way encryption for kaarel.sikk@gmail.com
ChatGPT:
- Two-way encryption is not a suitable solution for obfuscating an email address on a webpage, as it requires sharing the encryption key to decrypt the email address. This would make the process insecure, as anyone could access the key and decrypt the email.
However, you can use a simple JavaScript-based approach to "hide" the email address from spam bots while still displaying it to users. Here's an example of how you can achieve this:
- In your
about.md
file, add the following HTML code where you want your email address to appear:
<span id="email-container"></span>
- Create a JavaScript file called
email.js
in your_includes
folder, and add the following code:
document.addEventListener("DOMContentLoaded", function () {
const emailContainer = document.getElementById("email-container");
if (emailContainer) {
const name = "kaarel.sikk";
const domain = "gmail.com";
emailContainer.innerHTML =
'<a href="mailto:' + name + '@' + domain + '">' + name + '@' + domain + "</a>";
}
});
This JavaScript code will set the email address as inner HTML of the email-container
element when the DOM content is loaded.
- Finally, include the
email.js
file in yourbase.njk
file just before the closing</body>
tag:
<script src="/_includes/email.js"></script>
</body>
With this approach, the email address is not visible in the source code and is only created when the page is loaded. This makes it harder for spam bots to scrape the email address. Keep in mind that this method is not foolproof, but it provides a basic level of obfuscation.
Person:
- But please do sth like a simple caesar shiffer, so those words are not present at all
ChatGPT:
- Sure, here's a simple Caesar cipher implementation to obfuscate your email address.
- In your
about.md
file, add the following HTML code where you want your email address to appear:
<span id="email-container"></span>
- Create a JavaScript file called
email.js
in your_includes
folder, and add the following code:
function caesarCipher(str, shift) {
return str
.split("")
.map(function (char) {
const code = char.charCodeAt(0);
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {
const isUpperCase = code <= 90;
const aCharCode = isUpperCase ? 65 : 97;
return String.fromCharCode(((code - aCharCode + shift) % 26) + aCharCode);
}
return char;
})
.join("");
}
document.addEventListener("DOMContentLoaded", function () {
const emailContainer = document.getElementById("email-container");
if (emailContainer) {
const encodedEmail = "pbxryy.fvxx@tznvy.pbz";
const shift = -13;
const decodedEmail = caesarCipher(encodedEmail, shift);
emailContainer.innerHTML =
'<a href="mailto:' + decodedEmail + '">' + decodedEmail + "</a>";
}
});
This JavaScript code includes a Caesar cipher function to encode and decode text. The email address is provided in its encoded form, and it's decoded with a shift of -13 when the page loads. The decoded email address is then set as the inner HTML of the email-container
element.
- Finally, include the
email.js
file in yourbase.njk
file just before the closing</body>
tag:
<script src="/_includes/email.js"></script>
</body>
This method provides a basic level of obfuscation by not having the email address visible in the source code in its original form. However, keep in mind that this method is not foolproof and can be deciphered by determined attackers.
Person:
- Sure, could you please create the code in a way that neither @ sign or word email are also not present?
ChatGPT:
- Sure, here's an updated version of the code that avoids using the
@
sign and the word "email" directly in the JavaScript code:
- In your
about.md
file, add the following HTML code where you want your email address to appear:
<span id="email-container"></span>
- Create a JavaScript file called
email.js
in your_includes
folder, and add the following code:
function caesarCipher(str, shift) {
return str
.split("")
.map(function (char) {
const code = char.charCodeAt(0);
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {
const isUpperCase = code <= 90;
const aCharCode = isUpperCase ? 65 : 97;
return String.fromCharCode(((code - aCharCode + shift) % 26) + aCharCode);
}
return char;
})
.join("");
}
document.addEventListener("DOMContentLoaded", function () {
const emailContainer = document.getElementById("email-container");
if (emailContainer) {
const encodedEmail = "pbxryy.fvxx[znvy]pbz";
const encodedAtSymbol = "[znvy]";
const shift = -13;
const decodedEmail = caesarCipher(encodedEmail, shift).replace(
encodedAtSymbol,
String.fromCharCode(64)
);
emailContainer.innerHTML =
'<a href="' +
"znvy" +
"to:" +
decodedEmail +
'">' +
decodedEmail +
"</a>";
}
});
In this version of the code, I replaced the @
sign with [znvy]
in the encoded email address. Then, after decoding the email address with the Caesar cipher, I replaced the [znvy]
placeholder with the actual @
sign using the String.fromCharCode(64)
method to generate the @
character.
Kaarel:
How to deploy eleventy static site to an existing digitalocean droplet?
ChatGPT: Deploy to Digitalocean
ChatGPT:
- To deploy an Eleventy static site to an existing DigitalOcean droplet, you'll need to follow these steps:
- Make sure your Eleventy project is built locally : Run
npx eleventy
ornpm run build
(if you have a build script) in the project folder to generate the static site files in the_site
folder (or other output folder if you have set a custom one). - Install an FTP client : Install an FTP client such as FileZilla to transfer your files to the DigitalOcean droplet.
- Configure your droplet : Make sure your droplet has a web server installed and configured (e.g., Nginx, Apache). If you haven't already done so, you can follow these guides for setting up Nginx or Apache on Ubuntu:
- Connect to your droplet via FTP : Open your FTP client and enter your droplet's IP address, username (usually
root
), and password or SSH key. Connect to the droplet. - Upload your Eleventy project : In the FTP client, navigate to the root directory of your web server (e.g.,
/var/www/html
for Apache or/var/www/your_domain
for Nginx). Delete any existing files or folders if necessary, then upload the contents of your_site
folder (or other output folder) to the root directory. - Configure your web server (if needed) : If you are using a custom domain, make sure you have set up the necessary DNS records and configured your web server to serve your domain. For Nginx, you'll need to create a server block configuration file in
/etc/nginx/sites-available/
and symlink it to/etc/nginx/sites-enabled/
. For Apache, you'll need to create a virtual host configuration file in/etc/apache2/sites-available/
and enable it using thea2ensite
command. - Restart your web server : Restart your web server to apply any configuration changes:
- For Nginx:
sudo systemctl restart nginx
- For Apache:
sudo systemctl restart apache2
- Visit your site : Open a web browser and navigate to your droplet's IP address or your custom domain. Your Eleventy static site should be displayed.
By following these steps, you'll successfully deploy your Eleventy static site to a DigitalOcean droplet.
Person:
- I have done droplet setup. Please write a bash script that can be run from my eleventy instance root directory which uploads static web with scp to : vinnetu@kaarel.sikk.info:/var/www/kaarel.sikk.info/new
ChatGPT:
- To create a bash script that uploads your static website using
scp
, you can create a file nameddeploy.sh
in the root directory of your Eleventy project and add the following contents:
#!/bin/bash
# Build the Eleventy project
echo "Building Eleventy project..."
npx eleventy
# Upload the static files using scp
echo "Uploading files to the server..."
scp -r _site/* vinnetu@kaarel.sikk.info:/var/www/kaarel.sikk.info/new
echo "Deployment complete."
After creating the deploy.sh
file, you need to make it executable by running the following command in your terminal:
chmod +x deploy.sh
Now you can deploy your Eleventy project by running the deploy.sh
script:
./deploy.sh
This script will first build your Eleventy project and then upload the contents of the _site
folder to the specified path on your server using scp
. Please ensure you have the correct authentication set up (password or SSH key) for scp
to work without prompting for a password.
Person:
- In my eleventy setup there is a problem, for testing I want it to be under /new/ but eleventy assumes it is under root directory, how to add for testing period, this /new in front of urls?
ChatGPT:
- You can configure Eleventy to use a different base URL during development by setting the
url
value in your Eleventy configuration file, usually.eleventy.js
. You can use environment variables to differentiate between production and development environments.
First, install the dotenv
package to load environment variables from a .env
file:
npm install dotenv
Create a .env
file in the root of your Eleventy project with the following content:
BASE_URL=/new
Then, in your .eleventy.js
file, require the dotenv
package at the top of the file and load the environment variables:
const dotenv = require('dotenv');
dotenv.config();
Next, add the url
property to the Eleventy configuration object:
module.exports = (eleventyConfig) => {
// Your existing Eleventy configuration...
return {
// ...
url: process.env.BASE_URL || '/',
// ...
};
};
Now, Eleventy will use the base URL specified in the .env
file during development. When you're ready to deploy to production, you can set the BASE_URL
environment variable to the root directory or just remove the .env
file.
In your templates, make sure to use the url
property when generating links. For example, in a Nunjucks template:
<a href="/about">About</a>
This will ensure that the correct base URL is used when generating links during development and production.
Person:
- How to do it that in local development instance there is no "/new", in test deployment there is "/new" and final deployment there is now "/new" ?
ChatGPT:
- To achieve this, you can create separate environment variables in the
.env
file for each environment (development, test, and production). Then, based on the environment, you can set the appropriate base URL in your Eleventy configuration.
First, update your .env
file with the following content:
DEV_BASE_URL=/
TEST_BASE_URL=/new
PROD_BASE_URL=/
Then, in your package.json
file, update your scripts to include an ENV
variable that specifies the environment:
"scripts": {
"start": "ENV=dev eleventy --serve",
"test": "ENV=test eleventy",
"build": "ENV=prod eleventy"
}
Next, in your .eleventy.js
file, modify the url
property in the Eleventy configuration object to use the appropriate environment variable based on the ENV
value:
module.exports = (eleventyConfig) => {
// Your existing Eleventy configuration...
let baseUrl;
switch (process.env.ENV) {
case 'dev':
baseUrl = process.env.DEV_BASE_URL;
break;
case 'test':
baseUrl = process.env.TEST_BASE_URL;
break;
case 'prod':
default:
baseUrl = process.env.PROD_BASE_URL;
break;
}
return {
// ...
url: baseUrl,
// ...
};
};
Now, when you run npm start
for local development, the base URL will be set to /
. When you run npm run test
for testing, the base URL will be set to /new
. And when you run npm run build
for production, the base URL will be set to /
.
Remember to update your templates to use the url
property when generating links, as shown in the previous answer.
Person:
- So how to run the deploy.sh to upload test environment
ChatGPT:
- To deploy the test environment, you should first build your Eleventy site using the test environment settings and then run your
deploy.sh
script. You can do this by updating yourpackage.json
scripts and adding a newdeploy-test
script.
Update your package.json
:
"scripts": {
"start": "ENV=dev eleventy --serve",
"test": "ENV=test eleventy",
"build": "ENV=prod eleventy",
"deploy-test": "ENV=test eleventy && sh deploy.sh"
}
This new deploy-test
script will first build your Eleventy site using the test environment settings (which include the /new
base URL), and then it will run your deploy.sh
script to upload the files to your server.
To deploy the test environment, run:
npm run deploy-test
This command will build your test environment and then execute your deploy.sh
script to upload the static files to your server.
Person:
- For some reason the urls after this do not begin with "/new"
ChatGPT:
- My apologies for the confusion. Let's update the
eleventy.js
file to use the environment variable correctly.
Update your eleventy.js
file:
module.exports = (eleventyConfig) => {
// Other configurations...
const env = process.env.ENV;
let baseUrl = '/';
if (env === 'test') {
baseUrl = '/new/';
}
eleventyConfig.addPassthroughCopy('css');
eleventyConfig.addPassthroughCopy('images');
// Other configurations...
return {
passthroughFileCopy: true,
dir: {
input: '.',
output: '_site',
includes: '_includes',
layouts: '_layouts',
},
// Add the following line to your config object
pathPrefix: baseUrl,
};
};
After updating your eleventy.js
configuration file, make sure you've updated your package.json
as described in my previous answer. Then, run npm run deploy-test
. This should generate the correct URLs with the /new
prefix for the test environment.
Person:
- How to debug and print out env contents while running it?
ChatGPT:
- You can add a
console.log()
statement inside youreleventy.js
file to print out the value of theenv
variable. This will help you debug and see the contents of the environment variable while running Eleventy.
Here's an example of how you can do that:
module.exports = (eleventyConfig) => {
// Other configurations...
const env = process.env.ENV;
console.log('Environment:', env); // This line will print out the value of env
let baseUrl = '/';
if (env === 'test') {
baseUrl = '/new/';
}
eleventyConfig.addPassthroughCopy('css');
eleventyConfig.addPassthroughCopy('images');
// Other configurations...
return {
passthroughFileCopy: true,
dir: {
input: '.',
output: '_site',
includes: '_includes',
layouts: '_layouts',
},
// Add the following line to your config object
pathPrefix: baseUrl,
};
};
After adding the console.log()
statement, you can run Eleventy (npm run build
, npm run serve
, or npm run deploy-test
) and see the output in your terminal. This will help you identify the current value of the env
variable and make sure it's being set correctly.
Person:
- It seems .env variables are not loaded
ChatGPT:
- It seems that you may not be using the
dotenv
package to load the environment variables from your.env
file. You'll need to install it and configure it in your Eleventy project.
First, install dotenv
using npm:
npm install dotenv
Next, require dotenv
at the top of your .eleventy.js
file and configure it to load the environment variables from your .env
file:
// Add these lines at the beginning of your .eleventy.js file
const dotenv = require('dotenv');
dotenv.config();
// Rest of your Eleventy configuration
module.exports = (eleventyConfig) => {
// ...
};
Now, when you run Eleventy, it should load the environment variables from your .env
file. Make sure your .env
file contains the necessary variables, like ENV=development
or ENV=test
.
If you are using version control like Git, add the .env
file to your .gitignore
file to prevent accidentally sharing sensitive information.
Person:
- Now I can see /new is going through to returned as baseUrl, but it is not in the final html?
ChatGPT:
- If you have correctly set the
baseUrl
in your.eleventy.js
file, you will need to make sure you are using it in your template files when constructing URLs.
For example, in your base.njk
or other layout files where you define your navigation menu or any other links, you should use the baseUrl
variable. Here's an example of how to use it with Nunjucks:
<!-- Example of using baseUrl in a navigation menu -->
<nav>
<ul>
<li><a href="/about">About</a></li>
<li><a href="/projects">Projects</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
Make sure you're using the baseUrl
variable in all places where you construct URLs, including internal links and resource paths (like CSS, JavaScript, and images).
After making these changes, your URLs should be correctly constructed based on the baseUrl
value you set in your environment. When you deploy your test environment, the baseUrl
should be /new
, and in your local development environment and final deployment, it should be an empty string.
Person:
- This is returned from .eleventy.js file, what does this returned pathPrefix do? return {
passthroughFileCopy: true,
dir: {
input: '.',
output: '_site',
includes: '_includes',
//layouts: '_layouts',
},
// Add the following line to your config object
pathPrefix: baseUrl,
};
ChatGPT:
- The
pathPrefix
option in the Eleventy configuration sets a URL prefix for your site's assets, internal links, and resource paths when the site is built. This is useful for deploying your site in a subdirectory or when you want to add a base URL to all your internal links and resources.
In your case, the baseUrl
variable is being used as the pathPrefix
. So, when you build your site with Eleventy, it will prepend the baseUrl
value to your site's links and resources.
However, you still need to use the baseUrl
variable in your template files when constructing URLs and resource paths, as I mentioned in the previous response. The pathPrefix
only affects how Eleventy generates the site's structure, but you need to make sure your template files use the correct URLs as well.
By setting the pathPrefix
in your .eleventy.js
file and using the baseUrl
variable in your templates, your site should have the correct URLs based on your environment. When you deploy your test environment, the baseUrl
should be /new
, and in your local development environment and final deployment, it should be an empty string.
Person:
- The code does not seem to access baseUrl
ChatGPT:
- I apologize for the confusion. Let's make sure the
baseUrl
is accessible in your templates. You can add thebaseUrl
as a global data value in your.eleventy.js
config file:
module.exports = function (eleventyConfig) {
// Your existing configuration code
// Load environment variables
require('dotenv').config();
// Set the baseUrl based on the environment
const baseUrl = process.env.NODE_ENV === 'test' ? '/new' : '';
// Pass the baseUrl to templates
eleventyConfig.addGlobalData('baseUrl', baseUrl);
// Your existing return statement
return {
// ...
pathPrefix: baseUrl,
};
};
Now, you should be able to access the baseUrl
in your templates using the global
object:
For example, in your base.njk
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Human-AI work on creation of this web page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<!-- Your existing content -->
</body>
</html>
Repeat the same pattern for any other URLs or resources in your templates.
Now, Eleventy should have the correct URLs based on your environment.