aria 테마 code block 변경하기

**라이벌(Rival)**은 동등 혹은 그 이상의 실력은 가진 경쟁자를 의미한다 적수라고도 한다.

위키백과

 라이벌이라는 존재는 존재 자체만으로 동기부여가 됩니다. 이번 포스트에서는 블로그를 시작하면서 생긴 라이벌 code block을 다뤄보도록 하겠습니다.

Prologue

Code Block

Before Patch

 aria 테마를 설치하고 처음 code block을 보고 이야 이거 물건이다라는 생각이 들었습니다. 뭐랄까 감성을 자극했다고 해야되나요? 쨌든 잘 다듬어서 써야겠다 라고 생각했습니다. 하지만 포스트 몇개를 올리게 되고, 블로그의 세팅을 변경하다보니 깨닫게 된 사실이 있었습니다.
code block
초기 code block은 왼쪽 상단의 복사 버튼, 동작은 하지 않지만 우측 상단의 최소화, 최대화, 닫기 버튼이 있고, 작업 표시줄 부분엔 code라는 문자열이 고정되어 있습니다.

Another dead pixel

 그렇다면 무엇이 문제일까요. 눈치가 빠르신 분이라면 아시겠지만 code block의 제목 부분이 code로 고정되어있습니다. 한가지 더 문제점이 있는데 이는 Mark Down 파일 작성 시 code block에 파일명을 넣어서 작성하는 경우 입니다.
code block with title
오늘 수고해주실 코드블럭입니다.

A wasted of Time

First step

사태 파악

 변경을 위해선 먼저 저 제목 부분이 어떤 tag를 달고 있는지 확인해야 합니다. chorme 개발자 도구를 활용해 봅시다.
code block tag1
code block tag2
확인해 보니 file name 부분은 figcaption tag를 사용하고 있고, title bar 부분은 div.code-titlebar tag를 사용하고 있습니다.

modify

 첫 삽질은 title bar에 code를 지우는 것이였습니다. 먼저 원본 코드를 보도록 하겠습니다.

./themes/aria/layout/_layout.njk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script defer type="text/javascript" src="{{ url_for("js/index.js") }}"></script>
<script type="text/javascript">
$(document).ready(function () {
var cb = null;
var els = $(".post figure.highlight");
if (els.length) {
// Enabled Hexo highlight line number.
$(els).each(function (i, e) {
// $(e).before("<button class=\"copy button\">{{ __("clipboard.copy") }}</button>");
$(e).before([
"<div class=\"code-titlebar\">",
"<div class=\"titlebar-left\">",
"<button class=\"copy\" aria-label=\"{{ __("clipboard.copy") }}\"><i class=\"far fa-copy\"></i></button>",
"</div>",
"<div class=\"titlebar-center\">",
"{{ __("") }}", //"{{ __("code") }}",
"</div>",
"<div class=\"titlebar-right\">",
"<button class=\"button-dot dot-minimize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-maximize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-close\" aria-label=\"Decoration\"></button>",
"</div>",
"</div>"
].join(""));
});

16번째 줄을 보면 “code”문자열을 지우면 제목 표시줄의 code를 지울 수 있습니다.
code block notitle1
제목 표시줄이 깔끔해졌습니다.
code block notitle2
하지만 file name을 사용한다면 디자인이 구려집니다. 그렇다고 제목을 포기할 수는 없습니다. 저는 code block에 제목을 다는 법을 알게 되버렸으니까요.


Second step

사태파악

&nbsp;두번째로 생각한 내용은 제목 표시줄에 표시할 수 없다면 file name css의 디자인을 code block에 맞추는 것이었습니다. 그리고 제목 표시줄 왼쪽에 copy 기능이 file name을 적으면 copy 기능이 제대로 동작하지 않는 버그도 발견했습니다. 아쉽게도 이번 step에서는 해당 버그를 고치진 못했고 버그가 있다는 것만 확인했습니다.

modify

&nbsp;변경해야될 figcaption tag의 css파일을 찾을 수 없었기에 index.styl 파일에 추가했습니다.

./themes/aria/source/css/index.styl
1
2
3
4
5
6
7
8
9
10
11
figcaption{
color: $color-code-titlebar-font;
background: #4f5258;
border-radius: $corner-radius;
padding: 0.25em;
padding-left: 1em;
padding-right: 1em;
position: relative;
display: inline;
text-align: center;
}

code block step2
file name에 css가 적용되었습니다.

&nbsp;한동안 figcaption에 css를 적용해 code block을 사용했습니다. 아무래도 front end 부분은 깊게 다뤄본 적이 없어서 지금 수준으론 문제를 해결할 수 없다고 판단해 공부를 더 했습니다.

The end

&nbsp;시간이 날때마다 aria의 코드를 보고 나름 구조를 파악하다 보니 DOM의 사용법과 JS의 사용법 등을 실험하다보니 copy버그와 titebar를 수정 할 수 있었습니다.

Copy

&nbsp;code block에 file name을 사용한다면 copy 기능이 왜 동작하지 않는지 알아야 했습니다. 수정 전의 원본 코드를 확인해보겠습니다.

./themes/aria/layout/_layout.njk
1
2
3
4
5
6
cb = new ClipboardJS("button.copy", {
"target": function (trigger) {
// Get target element by DOM API.
return trigger.parentNode.parentNode.nextElementSibling.firstChild.firstChild.firstChild.lastChild.firstChild.firstChild;
}
});

해당 코드는 _layout.njk 파일의 일부입니다. copy button을 click하면 return에 해당하는 object를 clip board에 copy하는 기능을 가지고 있습니다. 해당 코드가 실행되면 file name이 없는 경우에는 정상적으로 copy하지만 file name이 있는 경우에는 아무런 동작을 하지 않습니다.

&nbsp;file name이 있어도 code를 return 할 수 있도록 return 부분을 수정해 보도록 하겠습니다.

./themes/aria/layout/_layout.njk
1
2
3
4
5
6
7
cb = new ClipboardJS("button.copy", {
"target": function (trigger) {
// Get target element by DOM cd API.
return trigger.parentNode.parentNode.nextElementSibling.lastChild.lastChild.lastChild.lastChild;
//return trigger.parentNode.parentNode.nextElementSibling.firstChild.firstChild.firstChild.lastChild.firstChild.firstChild;
}
});

file name을 사용하더라도 code만 clip board에 복사 해 올 수 있습니다.


Title bar

&nbsp;titlebar를 수정하면서 했던 삽질 중에 가장 기억에 남는 것은 code block모든 text를 읽어와서 조건문을 사용해 file name만 추출하는 방법이었습니다. 물론 code block 마다 조건문이 동작했기 때문에 포스팅에 code block이 많거나 code block의 text가 많다면 페이지 로딩 시간이 3~5초 길게는 10초 이상도 걸렸던 적이 있습니다.
&nbsp;copy 기능의 버그를 수정하면서 했던 몇가지 실험을 성공해 title bar에도 적용할 수 있었습니다. 아래는 원본 코드의 일부분입니다.

./themes/aria/layout/_layout.njk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$(document).ready(function () {
var cb = null;
var els = $(".post figure.highlight");
if (els.length) {
// Enabled Hexo highlight line number.
$(els).each(function (i, e) {
// $(e).before("<button class=\"copy button\">{{ __("clipboard.copy") }}</button>");
$(e).before([
"<div class=\"code-titlebar\">",
"<div class=\"titlebar-left\">",
"<button class=\"copy\" aria-label=\"{{ __("clipboard.copy") }}\"><i class=\"far fa-copy\"></i></button>",
"</div>",
"<div class=\"titlebar-center\">",
"{{ __("code") }}",
"</div>",
"<div class=\"titlebar-right\">",
"<button class=\"button-dot dot-minimize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-maximize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-close\" aria-label=\"Decoration\"></button>",
"</div>",
"</div>"
].join(""));
});

$(e).before에서 ecode block의 내용을 담고 있는 object라는 걸을 유추 할 수 있습니다. 그렇다면 e를 어떻게 지지고 볶으면 원하는 file name을 얻어 낼 수 있지 않을까 해서 조져봤습니다.

./themes/aria/layout/_layout.njk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$(document).ready(function () {
var cb = null;
var els = $(".post figure.highlight");
if (els.length) {
// Enabled Hexo highlight line number.
$(els).each(function (i, e) {
var codeTitle = "";
var codeContents = e.firstChild.innerText;
// codeContents - 1 or file name
if (codeContents[0] == 1){
codeTitle = "CMD";
}else{
codeTitle = codeContents
}
// $(e).before("<button class=\"copy button\">{{ __("clipboard.copy") }}</button>");
$(e).before([
"<div class=\"code-titlebar\">",
"<div class=\"titlebar-left\">",
"<button class=\"copy\" aria-label=\"{{ __("clipboard.copy") }}\"><i class=\"far fa-copy\"></i></button>",
"</div>",
"<div class=\"titlebar-center\">",
codeTitle,
"</div>",
"<div class=\"titlebar-right\">",
"<button class=\"button-dot dot-minimize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-maximize\" aria-label=\"Decoration\"></button>",
"<button class=\"button-dot dot-close\" aria-label=\"Decoration\"></button>",
"</div>",
"</div>"
].join(""));
});

추가한 코드에 대해 간략히 설명하면 다음과 같습니다

  • codeTitle - code title이 저장될 변수
  • codeContents - DOM을 저장할 변수
  • if 문 - file name이 없다면 codeTitle에 “CMD”를 저장, file name이 없다면 codeTitlecodeContents(file name)을 저장

&nbsp;css를 적용했던 figcaption tag가 안보이도록 변경하겠습니다. 주의 사항으로는 visibility: hidden 속성을 주면 DOM에도 포함이 안되기 때문에 title bar에도 표시되지 않습니다. css를 다음과 같이 변경합니다.

./themes/aria/source/css/index.styl
1
2
3
figcaption {
font-size: 0;
}

약간 편법 같지만 원하는 디자인으로 나와줄 것입니다.

codeblock end

원하던 모양으로 code block이 완성되었습니다. 상당히 마음에 듭니다.

Epilogue

&nbsp;블로그 초기부터 꽤나 고치고 싶었던 부분이였는데 원하는 디자인으로 변경할 수 있어 상당히 뿌듯합니다.