Host a Ghost Blog on AWS in 2023 (III) - Blog Customization
Now that the website is up, customization should come into play to address specific functional and aesthetic needs, in this post, there are a few improvements that I have done to make it better. Please note that there are a lot of tutorials already so this post just put things together.
Besides, for those who are interested in building the blog, the prior 2 parts are the go-to reference:
1 Functional Enhancement
1.1 Back Up Periodically
Periodical backup ensure that you can easily restore your website when something unexpected happens. So far if you self host the blog, Ghost suggests you go to Ghost Admin, then Labs
and export the content yourself periodically.
This will be a .json
file, with a name like my-site.ghost.2020-09-30-14-15-49.json
1.2 Deploy Custom Theme via GitHub
This automatic pipeline saves a lot of time of uploading custom themes to your website.
More info can be found in the Ghost official tutorial:
1.3 Set up Mail Delivery Service
Ghost has the ability to deliver posts as email newsletters natively. In order to do this, the bulk mail API has to be set up and now Ghost only supports Mailgun.
Go to the Newsletter
section of your Ghost Admin, get the domain name and private APIs from Mailgun.
1.4 Configure Comment System
Now Ghost supports native comment system that allows members to comment on your post:
Or you can set up Disqus to make the settings more flexible:
2 Aesthetic Enhancement
2.1 Custom Theme
You can use whatever theme you like if you host the Ghost application yourself, that is a great benefit in my eyes, below is the official reference materials to develop your own theme:
2.2 Move-to-Top button
This can be addressed by inserting code in the header and footer easily. First insert below code snippet into the header
:
<!-- Reading progress bar -->
<style>
.reading-progress {
position: fixed;
top: 0;
z-index: 999;
width: 100%;
height: 5px; /* Progress bar height */
background: #c5d2d9; /* Progress bar background color */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none; /* Hide default progress bar */
}
.reading-progress::-webkit-progress-bar {
background-color: transparent;
}
.reading-progress::-webkit-progress-value {
background: var(--ghost-accent-color); /* Progress bar color */
}
</style>
<!-- Scroll Top Button -->
<style>
/*Scroll to Top CSS*/
.scroll-top {
position: fixed;
z-index: 50;
padding: 0;
right: 30px;
bottom: 100px;
opacity: 0;
visibility: hidden;
transform: translateY(15px);
height: 46px;
width: 46px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all .4s ease;
border: none;
box-shadow: inset 0 0 0 2px #ccc;
color: #ccc;
background-color: #fff;
}
.scroll-top.is-active {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.scroll-top .icon-tabler-arrow-up {
position: absolute;
stroke-width: 2px;
stroke: #333;
}
.scroll-top svg path {
fill: none;
}
.scroll-top svg.progress-circle path {
stroke: #333;
stroke-width: 4;
transition: all .4s ease;
}
.scroll-top:hover {
color: var(--ghost-accent-color);
}
.scroll-top:hover .progress-circle path, .scroll-top:hover .icon-tabler-arrow-up {
stroke: var(--ghost-accent-color);
}
</style>
<button class="btn-toggle-round scroll-top js-scroll-top" type="button" title="Scroll to top">
<svg class="progress-circle" width="100%" height="100%" viewBox="-1 -1 102 102">
<path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<line x1="12" y1="5" x2="12" y2="19" />
<line x1="18" y1="11" x2="12" y2="5" />
<line x1="6" y1="11" x2="12" y2="5" />
</svg>
</button>
Then insert the code snippet into the footer
:
<!-- Scroll Top Button -->
<script>
const scrollTopBtn = document.querySelector('.js-scroll-top');
if (scrollTopBtn) {
scrollTopBtn.onclick = () => {
window.scrollTo({top: 0, behavior: 'smooth'});
}
const progressPath = document.querySelector('.scroll-top path');
const pathLength = progressPath.getTotalLength();
progressPath.style.transition = progressPath.style.WebkitTransition = 'none';
progressPath.style.strokeDasharray = `${pathLength} ${pathLength}`;
progressPath.style.strokeDashoffset = pathLength;
progressPath.getBoundingClientRect();
progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear';
const updateProgress = function() {
const scroll = window.scrollY || window.scrollTopBtn || document.documentElement.scrollTopBtn;
const docHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
const windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
const height = docHeight - windowHeight;
var progress = pathLength - (scroll * pathLength / height);
progressPath.style.strokeDashoffset = progress;
}
updateProgress();
const offset = 100;
window.addEventListener('scroll', function(event) {
updateProgress();
//Scroll back to top
const scrollPos = window.scrollY || window.scrollTopBtn || document.getElementsByTagName('html')[0].scrollTopBtn;
scrollPos > offset ? scrollTopBtn.classList.add('is-active') : scrollTopBtn.classList.remove('is-active');
}, false);
}
</script>
3 Conclusion
Through above improvement, the website will become more user friendly and accessible, hope it helps.