Firefox OS용 노트 앱 만들기 개발 사례

이 글은 Building a persistent Notes app for Firefox OS의 한국어 번역본입니다.

이번 튜토리얼에서 우리는 (에버노트 같은) 노트 앱을 맨바닥부터 만들고 Firefox OS에 설치해볼 것입니다! 라이브 데모에서 이제부터 만들 노트 앱이 동작하는 모습을 미리 볼 수 있습니다.

노트 앱은 사용자의 노트를 저장할 수 있는 독립된 공간을 필요로 합니다 (이 공간의 내용을 다른 사용자는 볼 수 없어야 합니다). 이를 구현하기 위해 저자가 만든 Sproute라는 백엔드(backend) 솔루션을 사용할 것입니다. Sproute는 다이나믹한 웹앱을 손쉽게 만들 수 있는 웹 프레임워크이며 호스팅 서비스 형태로 제공됩니다.

우선 고유한 서브도메인 이름을 정하고 계정을 만듭니다. 그리고 http://<mysubdomain>.sproute.io/admin 주소로 대시보드(Dashboard)에 접속합니다. 대시보드를 사용하려면 Sprotue에 가입할 때 입력한 정보로 로그인해야 합니다.

모델(Models)

Sproute 프레임워크에는 모델이라는 개념이 있습니다. 모델은 앱에 필요한 동적인 데이터를 정의합니다. 그리고 모델에는 데이터 무결성을 관리하기 위한 속성도 존재합니다. notes라는 이름으로 아래와 같은 필드(fields)와 속성을 갖는 모델을 생성합시다.

  • body: Text, Required, Min: 1
  • sharing: Text, Allowed Values: public, private, Default Value: private
The model form filled out for notes

notes 모델 생성을 위한 폼(form)

body 필드에는 노트의 내용을 저장할 것입니다. sharing 필드에는 노트가 (링크를 통해) 다른 사람이 볼 수 있는 공개 노트인지 아니면 비공개 노트인지를 저장할 것입니다. 이것이 우리가 새로 정의할 모든 것입니다. 이 외에 필요한 모든 것은 내장된(built-in) 필드로 존재합니다.

노트 목록

우리는 사용자의 노트 목록을 나열하는 방법을 마련해야 합니다. 이 일은 페이지(page)라는 개념으로 구현할 수 있습니다. 페이지는 데이터를 뽑아내고 처리하는 템플릿 태그(template tags)를 포함하는 HTML 입니다.

index 페이지를 열어봅시다. index 페이지는 다른 사람들이 당신의 공간을 들여다 볼 때 처음 보여지는 홈페이지 입니다. 우리는 여기에 노트 목록을 나열할 것입니다. 다음 코드를 추가합시다.

{{ get /data/notes?sort=_lastUpdated,desc as notes }}

모든 데이터는 HTTP 인터페이스를 통해 조회됩니다. 따라서 {{ get }} 태그는 반드시 URL을 가져야 합니다. 위의 리퀘스트(request) 구문은 로그인된 사용자의 모든 노트 목록을 조회해서 notes라는 이름의 변수에 저장하는 역할을 합니다. 우리는 쿼리 파라메터를 통해 가장 최근에 수정된 노트가 처음에 오도록 조회 결과를 정렬합니다 (밑줄 표시는 내장된 필드임을 나타냅니다).

이제 노트 목록을 표시합시다.

<ul>
    {{ each notes as note }}
        <li><a href="/view/{{note._id}}">
        {{ word note.body 0 5 }}
        </a></li>
    {{ / }}
</ul>

{{ word }} 템플릿 태그는 body 필드의 처음 5 단어를 축출할 것입니다. /view/<id> URL은 아직 만들지 않은(잠시 후 만들) 어떤 페이지에 연결됩니다. note._id는 내장된 고유 식별자입니다.

Add the above code in the 'index' page

위의 코드를 ‘index’ 페이지에 추가하세요

노트 만들기

노트를 표현하는 페이지(view 페이지)를 만들기 전에, 노트를 만드는 페이지(create 페이지)를 만들어 봅시다. create라는 이름으로 새 페이지를 만듭니다. 그리고 아래 HTML을 추가합니다.

<form action="/data/notes?goto=/" method="post">
    <div><textarea name="body"></textarea></div>
    <div><select name="sharing">
        <option value="private">Private</option>
        <option value="public">Public</option>
    </select></div>
    <button type="submit">Create Note</button>
</form>

간단하지 않나요? 앞서 이야기한 것처럼, 모든 데이터는 HTTP 인터페이스를 통해 조회되고 수정됩니다. 이것은 우리가 간단한 HTML 폼(form)을 이용해서 새로운 노트를 만들 수 있다는 것을 의미합니다. goto 쿼리 파라메터는 사용자를 지정된 URL(여기서는 /)로 이동시키는 역할을 합니다.

이것은 새로운 페이지이기 때문에 이 페이지에 접근하기 위한 route(경로)를 새로 만들어야 합니다. route는 URL 패턴입니다. 요청된 URL이 패턴에 일치하면 해당 페이지가 그려집니다. index 페이지에 대해서는 이미 route가 존재함을 볼 수 있습니다. Routes 필드를 클릭해서 아래와 같이 새로운 route를 만듭시다.

  • Route: /create, Page: create.
New route to 'create' page

‘create’ 페이지를 위한 새로운 route

사용자 로그인과 사용자 등록

사용자 계정은 Sproute에 내장되어 있지만, 그래도 우리는 Register(사용자 등록) 페이지와 Login(로그인) 페이지를 만들어야 합니다. 고맙게도 이것 역시 간단한 HTML 폼(form)입니다. users라는 이름으로 페이지를 만들고 아래와 같이 내용을 채웁시다.

<h2>Login</h2>
<form action="/api/login?goto=/" method="post">
    <label>
        <div>Username:</div>
        <input type="text" name="name" />
    </label>
    <label>
        <div>Password:</div>
        <input type="password" name="pass" />
    </label>
    <button type="submit">Login</button>
</form>

이제 같은 페이지에 Login 폼을 복사해서 Register 폼을 추가한 다음에 액션(action) 속성을 /api/register로 바꿉시다. 그리고 새로운 route 2개를 아래와 같이 만듭니다.

  • Route: /login, Page: users
  • Route: /register, Page: users

노트 보기와 노트 수정하기

좀 전에 우리는 노트를 보기 위한 링크를 만들었습니다. 이 링크는 사용자가 노트를 수정하는 용도로도 사용될 것입니다. view라는 이름으로 새로운 페이지를 만들고 다음과 같이 내용을 채웁시다.

{{ get /data/notes/_id/:params.id?single=true admin as note }}
 
{{ if note.sharing eq private }}
    {{ if note._creator neq :session.user._id }}
        {{ error This note is private }}
    {{ / }}
{{ / }}
 
<form action="/data/notes/_id/{{params.id}}?goto=/" method="post">
    <div><textarea name="body">{{note.body}}</textarea></div>
    <div><select name="sharing">
       <option value="private" selected>Private</option>
       <option value="public">Public</option>
    </select></div>
    <button type="submit">Update Note</button>
</form>

먼저 요청된 노트의 내용을 얻기 위한 URL 리퀘스트를 만듭니다 (param 객체의 활용을 눈여겨 보세요). single=true 쿼리 파라메터는 1개의 컬렉션이 아닌 1개의 객체가 리턴되도록 지시합니다. admin 파라메터는 리퀘스트가 실행될 권한(사용자-타입)을 지시합니다. 그 다음 해당 노트가 private(비공개)인지 확인합니다. 만약 비공개 노트라면 해당 노트를 요청한 사용자가 노트의 작성자가 아닐 경우 에러를 발생시킵니다

수정 폼(update form)은 작성 폼(create form)과 매우 유사합니다. 단지 URL에 명시된 _id에 해당하는 노트를 수정하도록 액션(action)을 변경하면 됩니다.

이 페이지는 약간 복잡한 route를 필요로 합니다. route를 만들 때 플레이스홀더(placeholder)를 이용해야 합니다. 그래서 /view/anything URL이 요청되면 view 페이지가 보여지고 anything 값이 변수에 담기도록 처리해야 합니다.

route를 아래와 같이 만듭니다.

  • Route: /view/:id, Page: view

이제 params.id가 어디서 유래하는지 알 수 있을 것입니다. params은 route 안의 모든 플레이스홀더와 그 값을 위한 객체입니다.

Permissions(권한)

Sproute에서 마지막으로 중요한 개념이 permissions입니다. permissions은 URL의 패턴을 정의한다는 점에서 route와 똑같습니다. 하지만 route처럼 어떤 페이지를 가리키는 것이 아니라 필요한 사용자-타입을 검증합니다.

Permissions을 클릭하고 아래 내용을 추가하세요:

  • Method: GET, Route: /data/notes, User: Owner
  • Method: GET, Route: /data/notes/*, User: Owner

이렇게 함으로써 사용자가 만든 노트만 목록에 나열되도록 보장할 수 있습니다 (i.e. owner). 두번째 permission 때문에, 우리는 {{ get }} 리퀘스트를 admin 사용자-타입으로 실행시켜야 합니다. 그렇지 않으면 해당 노트가 공개(public)일 경우에도 (admin과 creator를 제외한) 모든 사람이 응답을 얻는데 실패할 것입니다.

Adding a permission to retrieving notes

노트를 조회하기 위한 permission 추가하기

Firefox OS 지원

Sproute을 이용하면 매우 쉽게 Firefox OS에서 실행되는 호스트형 앱을 만들 수 있습니다. 단지 매니페스트 JSON 데이터를 내용으로 갖는 페이지를 만들고 route를 /manifest.webapp이라고 지정하면 됩니다.

manifest라는 이름으로 아래와 같은 새 페이지를 만듭시다.

{
    "name": "{{self.name}}",
    "description": "A persistent notes app",
    "launch_path": "/",
    "icons": {
        "128": "/absolute/path/to/icon"
    }
}

/manifest.webapp 패턴의 route(경로)를 만들고 manifest 페이지를 가리키게 합니다.

다됐습니다! 이것을 manifest (http://notes.sproute.io/manifest.webapp) 링크를 이용해서 앱 관리자에서 테스트 해봅시다. Sproute는 GitHub에 공개된 오픈소스입니다. Mozilla Public License v2 라이선스 정책을 따르기 때문에 레포(repo)를 클론(clone)해서 개인적인 용도로 운영해도 됩니다.

Notes app at mobile width

모바일 화면 폭에서 실행되는 노트 앱

작성자: ingeeKim

"누구에게나 평등하고 자유로운 웹"에 공감하는 직장인.

ingeeKim가 작성한 문서들…


댓글이 없습니다.

댓글 쓰기