이 기능은 Hotwire와 StimulusJS를 중심으로 구축됩니다.### 텍스트 선택 및 노트 생성 다이얼로그* StimulusJS 컨트롤러: app/views/articles/show.html.erb
의 <p>
요소에 notes
Stimulus 컨트롤러를 연결하고, mouseup
이벤트를 notes#newNote
액션에 바인딩합니다. article_id
는 데이터 값으로 전달됩니다.* 오프셋 계산: notes_controller.js
의 #selectionOffsets
게터는 선택된 텍스트의 시작 및 끝 오프셋을 계산합니다. 이는 HTML 태그로 인해 텍스트 노드가 분할될 수 있는 복잡한 상황을 document.createTreeWalker
를 사용하여 처리합니다.* 다이얼로그 표시: newNote
액션은 계산된 오프셋을 사용하여 #showNoteDialog
를 호출하고, 이는 /notes/new
경로로 GET
요청을 보냅니다. 이때 responseKind: "turbo-stream"
을 지정하여 Turbo Stream 응답을 기대합니다.* 노트 폼 렌더링: NotesController#new
액션은 전달된 파라미터로 Note
객체를 초기화하고, new.turbo_stream.erb
뷰는 turbo_stream.append_all "body"
를 통해 노트 생성 폼이 포함된 <dialog>
를 페이지에 동적으로 추가합니다. 폼에는 article_id
, start_offset
, end_offset
이 숨겨진 필드로 포함됩니다.### 노트 저장 및 하이라이트 표시* 노트 저장: 사용자가 폼을 제출하면 NotesController#create
액션이 호출되어 노트를 저장하고, 성공 시 해당 기사 페이지로 리디렉션합니다.* 텍스트 하이라이트: highlighted_text
헬퍼 메서드는 article.body
에 저장된 노트를 순회하며 <mark>
태그를 삽입합니다. 이때 start_offset
을 기준으로 정렬하여 올바른 순서로 하이라이트가 적용되도록 합니다. offset
변수를 사용하여 삽입으로 인한 문자열 길이 변화를 보정하고, style='background-color: #{note.color}'
를 통해 각 노트의 색상을 반영합니다.### 마우스 오버 시 노트 표시* Turbo Frame 삽입: highlighted_text
헬퍼는 각 <mark>
태그 내부에 turbo-frame
을 추가합니다. 이 turbo-frame
은 src
속성을 통해 note_path(note)
를 가리키며 loading='lazy'
로 설정됩니다.* CSS 제어: CSS 규칙을 사용하여 mark
요소 내의 turbo-frame
은 기본적으로 display: none
으로 숨겨져 있다가, mark:hover
시 display: block
으로 변경되어 노트 내용을 표시합니다.
Hotwire와 StimulusJS를 활용한 Rails 블로그 텍스트 하이라이트 및 노트 기능 구현
Adding Text Highlights and Notes in Rails with Hotwire
작성자
발행일
2025년 09월 02일
핵심 요약
- 1 Hotwire와 StimulusJS를 사용하여 Rails 블로그에 텍스트 하이라이트 및 노트 생성 기능을 구현하는 방법을 상세히 설명합니다.
- 2 사용자가 선택한 텍스트의 시작 및 끝 오프셋을 정확히 계산하고, 이를 기반으로 노트 생성 다이얼로그를 동적으로 표시합니다.
- 3 `<mark>` 태그와 `turbo-frame`을 활용하여 하이라이트된 텍스트와 마우스 오버 시 노트를 동적으로 표시하는 기법을 소개합니다.
도입
본 문서는 블로그 애플리케이션에서 사용자가 기사 내 텍스트를 하이라이트하고 해당 하이라이트에 노트를 첨부할 수 있는 기능을 구축하는 방법을 다룹니다. 사용자가 텍스트를 선택하면 하이라이트 색상과 노트를 입력하는 다이얼로그가 나타나고, 나중에 하이라이트된 텍스트에 마우스를 올리면 해당 노트가 표시됩니다. 이 기능은 Hotwire와 StimulusJS를 활용하여 구현되며, `Article` 및 `Note` 모델을 설정하는 것부터 시작합니다. `Article` 모델은 제목과 본문을 포함하고, `Note` 모델은 `article_id`, `body`, `start_offset`, `end_offset`, `color`를 저장하여 하이라이트 정보를 관리합니다.
결론
Hotwire와 StimulusJS를 활용한 이 접근 방식은 복잡한 텍스트 하이라이트 및 노트 기능을 Rails 애플리케이션에 효율적으로 통합할 수 있음을 보여줍니다. 특히, 텍스트 선택 오프셋을 정확히 계산하고, Turbo Streams를 통해 동적으로 UI를 업데이트하며, `<mark>` 태그와 `turbo-frame`을 조합하여 인터랙티브한 사용자 경험을 제공하는 방식은 Hotwire의 강력함을 잘 드러냅니다. 이 구현은 서버 측 렌더링의 장점을 유지하면서 클라이언트 측의 풍부한 상호작용을 가능하게 하여, 개발 효율성과 사용자 만족도를 동시에 높이는 실용적인 해결책을 제시합니다.