서론
지난 글에서 tui editor에 plugin을 적용해 봤었다.
다만 해당 plugin은 css가 없는 단순 기능 추가였어서 현재 코드의 문제가 드러나지 않았었는데
이번에 적용하는 code-syntax-highlight에서 아주 대차게 고생시켰다.
해당 플러그인은 codeblock에서 문법 강조 효과를 주는 플러그인으로,
블로그 글도 올리고(js, vue) swift도 포스팅도 올리고, 후에 올릴 다른 프로젝트에 관한 글들까지 생각하면
문법적으로나 시각적으로나 구별이 좀 필요할 것 같다고 생각이 들었다.
책을 안 읽은 사람보다 한 권만 읽은 사람이 더 무섭다고 했던가...
어줍잖은 지식으로 기고만장하면 어떻게 되는지 뼈저리게 느꼈다.
이번 포스팅은 tui editor의 기본 플러그인인 code-syntax-highlight를 적용하며 생긴 문제점과,
블로그 운영에 대해서다.
본론
설치
설치는 이전의 게시물과 동일하다.
tui editor의 git 문서를 참고하자.
$ npm install @toast-ui/editor-plugin-code-syntax-highlight
or
$ yarn add @toast-ui/editor-plugin-table-merged-cell
지난번과 마찬가지로 환경에 맞게 사용하자.
저번도 그렇고 이번도 그렇고 yarn으로는 추가가 안 되는데...
이건 내가 그냥 쓰는 것 밖에 못해서 그런 것 같기도 하고...
npm으로 설치해도 증발하는 dependancies는 다시 추가해 주면 되니 크게 문제 될 건 없다. (이전 글)
import & instance
css import
import 하는 것도 크게 다를 것 없다.
서론에서 말 했듯 해당 플러그인은 css와 함께 동작하니 css를 import해 주지 않는다면
제대로 동작하지 않는다.
chillog는 \plugins\editor.js로 에디터를 관리하고 있으니 해당 파일에 추가해 주도록 하자.
import Vue from 'vue'
import 'codemirror/lib/codemirror.css'
import 'highlight.js/styles/github.css' //code-syntax-highlight css import
import '@toast-ui/editor/dist/toastui-editor.css'
import '@toast-ui/editor/dist/toastui-editor-viewer.css'
import '@toast-ui/editor/dist/i18n/ko-kr'
import { Editor, Viewer } from '@toast-ui/vue-editor'
Vue.component('viewer', Viewer)
Vue.component('editor', Editor)
이건 내가 참고하고있는 강의와 나만의 규칙이니 개인의 방식이 있으면 그에 맞게 적용하거나,
plugin을 import하는것과 동시에 진행해도 무방한 것을 확인했다.
해당 css는 코드블럭의 테마에 관련 된 것을 보이는데 현재까지 사용한 코드블럭이 웹페이지와 조화스럽지 않아 바꿔보는 것도 좋을 것 같다.
plugin import
plugin import는 실제 에디터를 사용하는 곳으로 가서 코드를 수정한다.
chillog의 경우 viewer를 사용하는 list-normal.vue와 content.vue, editor를 사용하는 form-normal.vue에서 코드를 수정해야 한다.
본격적으로 plugin을 사용하기 위해 다음의 코드를 추가한다.
import codeSyntaxHighlight from '@toast-ui/editor-plugin-code-syntax-highlight'
import hljs from 'highlight.js'
css import는 여기서 이루어 져도 괜찮다.
plugin을 editor의 option에 추가해 줘야 하는데 이 때 codeblock내의 언어를 감지하는 hljs와 함께 넘겨 줘야 highlight가 제대로 작동 한다.
위에서부터 나온 쌩뚱맞은 highlight.js는 이번 plugin의 의존성 모듈로 다행히 tui-editor 설치시에 함께 설치 되다.
때문에 이전에 셀병합 plugin을 추가했던 것과는 조금 다른 형대로 작성한다.
export default {
components: { DisplayTime, DisplayUser, DisplayTitle, DisplayCount },
props: ['items', 'boardId', 'category'],
data () {
return {
tuiOptions: {
plugins: [tableMergedCell, [codeSyntaxHighlight, { hljs }]], //plugin import
linkAttribute: {
target: '_blank'
}
},
getSummary
}
},
computed: {
fireUser () {
return this.$store.state.fireUser
}
},
methods: {
read (item) {
this.$router.push({ path: this.$route.path + '/' + item.id })
},
liked (item) {
if (!this.fireUser) return false
return item.likeUids.includes(this.fireUser.uid)
},
onViewerLoad (v) {
addYoutubeIframe(v.preview.el, this.$vuetify.breakpoint)
}
}
}
기본적으로 plugin들은 스퀘어 브라켓 내에서 컴마로 구별 되고,
배열형으로 전달해야 할 때는 다시 스퀘어 브라켓에서 컴마와 브레이스로 전달한다.
아래는 list-normal.vue의 최종 코드이다.
<template>
<div>
<template v-for="(item, i) in items">
<v-card :key="item.id" :class="$vuetify.breakpoint.xs ? '' : 'ma-4'" :flat="$vuetify.breakpoint.xs">
<v-card color="transparent" flat :to="category ? `${boardId}/${item.id}?category=${category}` : `${boardId}/${item.id}`">
<v-card-subtitle class="text--primary body-1" :class="item.important > 0 ? 'text-truncate': ''">
<display-title :item="item"/>
<v-spacer/>
<display-count v-if="item.important > 0" :item="item" :column="false"></display-count>
</v-card-subtitle>
<template v-if="!item.important">
<v-card-text>
<viewer class="tui-dark" v-if="item.summary" :initialValue="item.summary" @load="onViewerLoad" :options="tuiOptions"></viewer>
<v-container v-else>
<v-row justify="center" align="center">
<v-progress-circular indeterminate></v-progress-circular>
</v-row>
</v-container>
</v-card-text>
<v-card-actions class="d-flex justify-center">
<v-btn text color="default" class="mb-4">
<v-icon left>mdi-dots-vertical</v-icon>
</v-btn>
</v-card-actions>
</template>
</v-card>
<template v-if="!item.important">
<v-card-actions>
<span class="font-weight-black caption ml-3"><display-time :time="item.createdAt"></display-time></span>
<v-spacer/>
<display-user :user="item.user"></display-user>
</v-card-actions>
<v-card-actions>
<v-spacer/>
<display-count :item="item" :column="false"></display-count>
</v-card-actions>
<v-card-text>
<v-row justify="start" align="center" class="px-4">
<v-btn
color="info"
depressed
small
outlined
class="mr-4"
:to="`${$route.path}?category=${item.category}`"
width="100"
>
{{item.category}}
<v-icon right>mdi-menu-right</v-icon>
</v-btn>
<v-chip small label outlined color="default" class="mt-2 mr-2 mb-2" v-for="tag in item.tags" :key="tag" v-text="tag"></v-chip>
</v-row>
</v-card-text>
</template>
</v-card>
<v-divider v-if="i < items.length -1 && $vuetify.breakpoint.xs" :key="i"/>
</template>
</div>
</template>
<script>
import DisplayTime from '@/components/display-time'
import DisplayUser from '@/components/display-user'
import DisplayTitle from '@/components/display-title'
import DisplayCount from '@/components/display-count'
import getSummary from '@/util/getSummary'
import addYoutubeIframe from '@/util/addYoutubeIframe'
// tui-editor plugins
import tableMergedCell from '@toast-ui/editor-plugin-table-merged-cell'
import codeSyntaxHighlight from '@toast-ui/editor-plugin-code-syntax-highlight'
import hljs from 'highlight.js'
export default {
components: { DisplayTime, DisplayUser, DisplayTitle, DisplayCount },
props: ['items', 'boardId', 'category'],
data () {
return {
tuiOptions: {
plugins: [tableMergedCell, [codeSyntaxHighlight, { hljs }]],
linkAttribute: {
target: '_blank'
}
},
getSummary
}
},
computed: {
fireUser () {
return this.$store.state.fireUser
}
},
methods: {
read (item) {
this.$router.push({ path: this.$route.path + '/' + item.id })
},
liked (item) {
if (!this.fireUser) return false
return item.likeUids.includes(this.fireUser.uid)
},
onViewerLoad (v) {
addYoutubeIframe(v.preview.el, this.$vuetify.breakpoint)
}
}
}
</script>
<style>
문제
삽질하기
용케 적용해 놨더니 무언가 이상하다.
같은 코드를 codeblock에 작성해도 결과가 다르게 나온다.
생각할 수 있는 가능성은
- plugin이 설치가 안 됐거나, import가 제대로 안 됐거나 아무튼 plugin이 문제다.
- css가 적용이 안됐다.
두 가지였다.
plugin이 제대로 작동하는지 확인 하는 방법은 간단하다.
첫 번째로 오류인데, 일단 콘솔에서 뜨는 오류는 없었다.
빌드도 별 내용 없이 잘 구동됐다.
두 번째는 소스를 뜯는 것이다.
웹개발의 장점은 브라우저의 개발자 도구들이 정말 잘 되어 있다는 점이다.
플로팅만 하면 소스까지 이동을 해 주다니... 감동이다...
쉽게 찾아간 곳에서 highlight.js의 작동 여부를 볼 수 있다.
사진의 오른쪽을 보면 코드의 키워드 별로 hljs의 적용 문법에 따라 제대로 분리하고 있는 것을 볼 수 있다.
결론은 css가 문제일 것 같다는 생각이 들었다.
확인 받기
모르는 걸 아는 채 했다가 뽀록나면 그게 창피한 거다.
난 누가봐도 초보이니 당당히 물어 보기로 했다.
tui가 네이버에서 튀어나온 걸로 알고 있는데 일단은 문의 내용들도 그렇고 답변하는 것도 그렇고 영문이 기본인 것 같아 영문으로 진행했다.
답변 내용은 이러하다.
답변 내용
코드 작성한 부분들은 정상이고,코드 강조는 이미 적용이 되어 있는 것 같다.css가 제대로 적용 됐는지 확인을 한 번 해 보는 것이 좋을 거다.
(이제 와서 하는 말이지만 멍청이에게 친절한 답변 감사드립니다. js87zz님...)
말 그대로 이젠 css의 차례이다.
일단은 삽질에 너무 많은 시간을 쏟았고, css는 또 어떻게 확인해야 할 지 피곤한 상황이라 swift 공부에 잠시 쏟았던 것 같다.
어제에야 문득 내가 다크모드 관련해서 tui의 css를 건드렸다는 것이 생각이 났다.
해결하기
해당 코드는 앱 최상위인 \src\app.vue에 작성되어 있다.
다크모드 관련이라 앱 전반에 걸쳐 적용이 되면 되겠구나 하는 생각에 한 발상이었다,
<style>
.white-space{
white-space: pre-wrap;
}
.tui-dark h1, .tui-dark h2, .tui-dark h3, .tui-dark h4, .tui-dark h5, .tui-dark h6, .tui-dark li, .tui-dark ol, .tui-dark p, .tui-dark pre, .tui-dark table, .tui-dark ul {
color: var(--v-primary-base) !important
}
.tui-dark code, .tui-dark span {
color: #323232 !important
}
.scroll::-webkit-scrollbar {
display: none;
}
.scroll {
height: 215px;
overflow-y: auto;
}
</style>
일단은 크게 건들지 않고 조금씩 바꿔 보면서 진행하기로 한다.
아마 내 생각인데 해당 코드를 옮기면 이번같이 거지같은 상황은 생기지 않으리라...
너무 상위 코드에 적용을 해 둔 거지 싶다.
<style>
.white-space{
white-space: pre-wrap;
}
.tui-dark h1, .tui-dark h2, .tui-dark h3, .tui-dark h4, .tui-dark h5, .tui-dark h6, .tui-dark li, .tui-dark ol, .tui-dark p, .tui-dark pre, .tui-dark table, .tui-dark ul {
color: var(--v-primary-base) !important
}
.tui-dark code {
color: #323232 !important
}
.scroll::-webkit-scrollbar {
display: none;
}
.scroll {
height: 215px;
overflow-y: auto;
}
</style>
하나씩 건들여 보며 span을 뺐을 때 css가 잘 적용 되는 것을 확인했다.
code를 뺐을 경우 글씨가 흰 색으로 변하는 걸 봐선 vuetify의 dark-mode에 영향을 받는 것으로 보인다.
이후에 테마를 바꾸면서 확인해 볼 필요가 있어 보인다.
결론
훨~~씬 보기 좋아졌다.
Log
2021.07.23.
블로그 이전으로 인한 글 옮김 및 수정.
'프로젝트 > Chillog (Blog)' 카테고리의 다른 글
해결해야 할 문제 (0) | 2021.07.23 |
---|---|
Google 검색에 등록하기 (#1) (0) | 2021.07.23 |
Toast UI Editor (tui editor) plugin 적용하기 (#1) (0) | 2021.07.23 |
왠진 모르겠지만 첨부한 사진이 날아가는 문제. (0) | 2021.07.23 |
운영하다보니 날 괴롭히는 editor 문제 (0) | 2021.07.23 |