6 min read

Customize the website with blogdown


R

The initial idea of building a personal website is just showcasing some of my works from design studios, I used to directly craft my HTML5 website without any framework and then handle my portfolio on platforms that provide cloud-based web development services. As I got more projects done recently, I became increasingly lazy to update my portfolio website and the price for using the cloud-based web services is incredibly expensive. So, I was looking for a more interesting way to organize my staffs. Yes, blogdown enabled me to rebuild my website using R and Markdown with a little bit of work on HTML5 and CSS. In this post, I am sharing my experience with customizing a website using the blogdown package. My website is available in this repo.

1. Setup

I had not used blogdown before so I just installed it first:

install.packages('blogdown')

Then, the first step was to setup a project using Rstudio: File -> New project... -> New directory -> website using blogdown. I like concise layout so I just went with the default theme yihui/hugo-lithium. Or, blogdown::new_site(theme = 'yihui/hugo-lithium') can do the same thing. After creating this new project, I ran blogdown::serve_site() to locally preview the website in the ‘Viewer’ tab of Rstudio. Clicking the show in the window button can open the website in the browser.

2. Customized home page

A blogdown project includes these documents and folders for customization purposes:
config.yaml: website configuration
content: pages and posts
public: all files for deploying the website
themes: templates for the website

In my case, I wanted a page for introducing all things about me. I ran blogdown:::new_content("about.md") to create a new page using Markdown in the “content” folder. This what I had in the /content:

/content
├── about.md
└── post <- posts are in this dirctory

I also needed to make sure it can be accessible. Therefore, I modified config.yaml to add a button in the navigation bar and link it to"about.md":

menu:
  main:
  - name: About
    url: /about/ 

In addition, I added another button linked to my previous design portfolio website because I don’t want to relocate over 400MB images at this point so I just linked to it (this has said one can link any external page using url):

menu:
  main:
  - name: About
    url: /about/ 
  - name: Archived Projects
    url: https://www.xxxxxx.com/

Eventually, I didn’t felt like using the page filled with posts as my home page. Thus, I added ome more button Posts and changed the urls in config.yaml:

menu:
  main:
    - name: About
      url: /
      weight: 1
    - name: Posts
      url: /post/
      weight: 2
    - name: Archived Projects
      url: https://www.xiaohaoy.com/
      weight: 3

/ is the home page address. Since all posts are in /content/post, I. By the way, I reorder the navigation buttons by setting weight. However, “About” was still not my home page even if I chnaged the url because the home page index.html is automatically generated by the template in /themes. And about.md are not able to be recognized as anything like index.html.

I found the solution in this post. First, under /content, I renamed about.md as _index.md so it can be seen as main page. Then, I modified _index.md to build it as home page:

---
site: blogdown:::blogdown_site
---

After doing this, the post page were no longer my home page and it can be accessed through the navigation bar. In other word, the previous about.md became the main page that can be accessed via root directory / while the post page is on /post. However, both the content of current home page and the list of posts were displayed on the home page while the list of posts had been a separate page. This was cased by the change of hugo-lithium. Well, it was not an issue but I needed to revert it somehow.

Second, I overwrote the setting for the template of post page /themes/hugo-lithium/layouts/_default/list.html to prevent displaying main content and the list of posts together. list.html looked like something like this:

{{ partial "header.html" . }}
<main class="content" role="main">
  {{ if .Content }}
  <article class="article">
    <div class="article-content">
      {{ .Content }}
    </div>
  </article>
  {{ end }}
  <div class="archive">
    {{ range (where .Data.Pages "Section" "!=" "").GroupByDate "2006" }}
    <h2 class="archive-title">{{ .Key }}</h2>
    {{ range .Pages }}
    <article class="archive-item">
      <a href="{{ .RelPermalink }}" class="archive-item-link">{{ .Title }}</a>
      <span class="archive-item-date">
        {{ .Date.Format "2006/01/02" }}
      </span>
    </article>
    {{ end }}
    {{ end }}
  </div>
</main>
{{ partial "footer.html" . }}

The first part of this template allow the main conted to be displayed and the rest of it can display all posts in a list. What I did was adding a condition statement for the second part to exclude the post list when building the index.html:

{{ partial "header.html" . }}
<main class="content" role="main">
  {{ if .Content }}
  <article class="article">
    {{ if .Title }}
    <h1 class="article-title">{{ .Title }}</h1>
    {{ end }}
    <div class="article-content">
      {{ .Content }}
    </div>
  </article>
  {{ end }}
  {{ if not .IsHome }}
  <div class="archive">
    {{ range (where .Data.Pages "Section" "!=" "").GroupByDate "2006" }}
    <h2 class="archive-title">{{ .Key }}</h2>
    {{ range .Pages }}
    <article class="archive-item">
      <a href="{{ .RelPermalink }}" class="archive-item-link">{{ .Title }}</a>
      <span class="archive-item-date">
        {{ .Date.Format "2006/01/02" }}
      </span>
    </article>
    {{ end }}
    {{ end }}
  </div>
  {{ end }}
</main>
{{ partial "footer.html" . }}

3. Style modification

One of main changes I did for the style of this website was fixing the navigation bar. I made the modification in /themes/hugo-lithium/static/css/main.css. Basically, I did two things: change the position attribute of header tag and add padding-top to content class:

.header {
  padding: 20px 0;
  position: fixed;
  background: #f5f5f5;
  border-bottom: 1px solid #eaeaea;
  width: 100%;
}

.content {
  max-width: 700px;
  margin: 40px auto 10px;
  padding: 0 15px;
  font-size: 16px;
  line-height: 1.7;
  color: #333;
  padding-top: 35px;
}

I also kept the changes consistent in @media (min-width: 600px) {}. Basically, any style-related or layout-related modification should be done in /themes. But this maybe make it more difficult to pull updates of this theme in the future. More approaches for theme customization are accessible in the book of blogdown.

3. Deployment

To make the website visible to everyone, I pushed this git repo to github and deployed the website on Netlify by connecting the github repo. The free domain provided by Netlify was fine but I would like to have my own domain. Netlify does support adding domain alias. Google does not provide domain services any more thus I went with Squarespace. Squarespace provides basic customized domain $20/yr.

After purchasing a domain from Squarespace, I added it to the domain management panel of Netlify. Meanwhile, I made serveral changes in domain management of Squarespace. First, I unlocked “domain lock” so that I can transfer it to Netlify. Then, I removed all default DNS settings and added Custom Records:

Host: @
Type: A
Priority: 
Data: 75.2.60.5

Finally, I verified the domain and renewed the SSL/TLS certificate on Netlify. It just took a couple of hours to set up the new domain for my website.