ムニエルブログ

ムニエルのブログ

はてなブログで技術ブログを書くための技術

このブログは技術ブログ的な側面もあるので、デザイン上技術記事に必要なところにはこだわっています。
ここでは、はてなブログで技術ブログを書くうえで行なっているカスタマイズについて紹介します。

シンプルなテーマを使う

技術ブログの記事は文字が主体であることが多いため、テーマはなるべくシンプルなものを選びましょう。
僕は、はてなブログ公式テーマのSmoothを使用しています。

デザインをカスタマイズする

はてなブログは技術ブログに特化しているわけではないので、そのままではデザイン上不足している点があります。
技術ブログに必要な要素を取り入れるために、デザインをカスタマイズしましょう。
まず、はてなブログのデザイン設定でフッタに次のようなHTMLを追加します。

<script>
(function () {
  window.addEventListener('DOMContentLoaded', () => {
    makeExternalLinkOpenInNewTab()
    addLabelToCodeBlocks()
    addColorCodePreviews()
  }, false)

  function makeExternalLinkOpenInNewTab () {
    getExternalLinkElements().forEach(link => {
      link.setAttribute('target', '_blank')
      link.setAttribute('rel', 'noopener noreferrer')
    })
  }

  function getExternalLinkElements () {
    return Array.from(document.querySelectorAll(`a[href^="http"]:not([href^="${location.origin}"])`))
  }

  function addLabelToCodeBlocks () {
    getCodeBlockElements().forEach(codeBlock => {
      const label = codeBlock.parentElement.dataset.label || codeBlock.dataset.lang
      if (label) {
        codeBlock.dataset.label = label
      }
    })
  }

  function getCodeBlockElements () {
    return Array.from(document.querySelectorAll('.entry-content pre.code'))
  }

  function addColorCodePreviews () {
    getColorCodeElements().forEach(code => {
      const color = code.textContent
      code.outerHTML = `${code.outerHTML}<span class="color-code-preview" style="background-color: ${color};"></span>`
    })
  }

  function getColorCodeElements () {
    return Array.from(document.getElementsByTagName('code'))
      .filter(code => isColorCode(code.textContent))
  }

  function isColorCode (text) {
    return text.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/)
  }
})()
</script>

また、デザインCSSに次のようなCSSを追加します。

/* code block label */
.entry-content pre.code[data-label] {
  position: relative;
  margin: 0 0 1.5em 0;
  padding: 1.6em 1em 1em;
}

.entry-content pre.code[data-label]::before {
  content: attr(data-label);
  background-color: #444;
  color: #fafafa;
  position: absolute;
  top: 0;
  left: 0;
  padding: 0 0.8em;
}

/* /code block label */

/* color code preview */
.color-code-preview {
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  border: 1px solid #d1d5da;
  border-color: rgba(27, 31, 35, 0.15);
  border-radius: 3px;
}

/* /color code preview */

これらのコードでやっていることについて、一つずつ解説していきます。

外部リンクを新規タブで開くようにする

技術ブログはMarkdownで書くことが多いかと思いますが、Markdownではリンクにtarget="_blank"を指定することができません。
外部リンクを新規タブで開くために、JavaScriptで動的にtarget="_blank"rel="noopener noreferrer"を追加しましょう。

function makeExternalLinkOpenInNewTab () {
  getExternalLinkElements().forEach(link => {
    link.setAttribute('target', '_blank')
    link.setAttribute('rel', 'noopener noreferrer')
  })
}

function getExternalLinkElements () {
  return Array.from(document.querySelectorAll(`a[href^="http"]:not([href^="${location.origin}"])`))
}

コードブロックにラベルを追加

技術ブログには、しばしばソースコードが登場します。
はてなブログではコードブロックにシンタックスハイライトが適用されますが、せっかくなのでラベルも表示しましょう。

function addLabelToCodeBlocks () {
  getCodeBlockElements().forEach(codeBlock => {
    const label = codeBlock.parentElement.dataset.label || codeBlock.dataset.lang
    if (label) {
      codeBlock.dataset.label = label
    }
  })
}

function getCodeBlockElements () {
  return Array.from(document.querySelectorAll('.entry-content pre.code'))
}
.entry-content pre.code[data-label] {
  position: relative;
  margin: 0 0 1.5em 0;
  padding: 1.6em 1em 1em;
}

.entry-content pre.code[data-label]::before {
  content: attr(data-label);
  background-color: #444;
  color: #fafafa;
  position: absolute;
  top: 0;
  left: 0;
  padding: 0 0.8em;
}

デフォルトでは言語名を表示しますが、コードブロックを<div data-label="ラベル"></div>で囲むことで表示するテキストを指定することもできます。
たとえば、<div data-label="index.js"></div>で囲むと以下のようになります。

const message = 'Hello World'
console.log(message)

カラーコードのプレビューを表示

技術ブログには、ときにはカラーコードが登場することもあります。
#F44336のようにカラーコードを記載すると、その横に色のプレビューを表示するようにしましょう。

function addColorCodePreviews () {
  getColorCodeElements().forEach(code => {
    const color = code.textContent
    code.outerHTML = `${code.outerHTML}<span class="color-code-preview" style="background-color: ${color};"></span>`
  })
}

function getColorCodeElements () {
  return Array.from(document.getElementsByTagName('code'))
    .filter(code => isColorCode(code.textContent))
}

function isColorCode (text) {
  return text.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/)
}
.color-code-preview {
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  border: 1px solid #d1d5da;
  border-color: rgba(27, 31, 35, 0.15);
  border-radius: 3px;
}

カラーコードかどうかは/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/という正規表現で判定しているので、#1#hatenaのような文字列は対象になりません。


はてなブログ Perfect GuideBook

はてなブログ Perfect GuideBook

  • 作者:JOE AOTO
  • 発売日: 2016/07/22
  • メディア: Kindle版