모바일 청첩장 만들기

Jiwontwopunch·2022년 7월 15일
0

독학

목록 보기
98/102
post-thumbnail

프로젝트 디렉터리 설명

쉽게 따라하는 모바일 웹 개발: jQuery Mobile부터 Node.js까지 예제

dist

grunt 빌드를 통해 생성되는 프로젝트 결과물, 해당 디렉터리만 웹서버에 배포된다.

docs

제이쿼리 모바일은 단일 페이지 애플리케이션 구조를 띠고 있다. 해당 페이지가 될 index.html의 body 부분이 저장돼있다.

helper

현재 Grunt에서 사용 중인 assemble은 핸들바 템플릿을 사용 중이고, 이 핸들바 템플릿은 사용자 정의 헬퍼를 만들어 사용할 수 있다.
helper는 이러한 헬퍼를 저장해놓은 공간이다.

includes

현 프로젝트의 <body>요소 안의 여러 개의 페이지가 기능별로 총 6개의 페이지로 구성돼 있는데, 이뿐만 아니라 각 페이지별로 공통으로 사용되는
footer, toolbar, 위젝, script 태그, css 링크 등의 파일도 별도로 나눠져 있다.

layout

index.html의 구조가 저장되어 있다. 기본 doctype, html, head, meta 태그가 저장된 파일이 저장되는 폴더라고 보면 된다.

resources

해당 프로젝트를 구성하기 위한 css, img, js 파일이 저장된다. Grunt로 빌드되면 dist 디렉터리에 복사된다.

Gruntfile.js

Grunt를 통해 프로젝트의 빌드를 수행한다. 이를 위해 Grunt의 설정 및 실행에 대한 내용이 저장되어 있는 파일이고 이 파일이 있어야 Grunt가 실행된다.

data.json

본 프로젝트는 Grunt와 assemble을 통해 index.html 파일이 생성된다. 이때 data.json에 저장된 데이터를 참조하는데, 청첩장의 특성상 신부/신랑 소개, 결혼식장 위치, 환영 문구, 이미지 경로 등 변경하기 쉽게 해당 정보를 JSON 형태로 선언해 놓았다. 이 JSON 정보를 변경하면 내용이 전혀 다른 청첩장 파일을 생성할 수 있다.

package.json

Grunt는 Node.js 기반으로 만들어진 도구이다. Grunt에서 사용 중인 여러 모듈이 npm 기반으로 배포돼 있고, Grunt에서도 이것을 사용한다.
모든 Node.js 기반 프로젝트는 package.json 파일을 포함하고 있다. 해당 파일을 통해 의존성 관리 및 배포 정보를 관리한다.

grunt 설치 에러 해결

$ npm install
$ grunt
CategoryInfo: ObjectNotFound: (axios:String) [], CommandNotFoundExce ption
$ npm install -g grunt-cli
$ grunt
$ grunt dev

$ grunt dev

http://localhost:8080이라는 내부 웹서버를 실행하며, 해당 URL로 접속하면 프로젝트를 확인할 수 있다.

프로젝트 구현

hbs와 {{}}, {{>}}

확장자는 html이 아니고 hbs이다. 그 이유는 assemble에서 템플릿 엔진으로 핸들바를 사용하기 때문. 이 hbs 파일이 assemble과 Grunt 빌드를 통해 HTML로 완성된다.

// layout/default.hbs
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{user.groom}} {{user.brider}}의 Wedding Invitation by using jQuery Mobile</title>
  {{>css}}
</head>
<body>
<div id="fb-root"></div>
{{>body}}
{{>script}}
</body>
</html>
  1. {{}}로 감싸진 부분은 data.json에 저장된 정보를 표현하는 데이터 형식
  2. {{>}}는 includes 디렉터리에 저장된 템플릿을 불러온다. {{>css}} 부분은 includes/css.hbs에 있는 템플릿을 불러와 대체된다.
  3. {{>body}}만 includes 디렉터리에 있는 템플릿을 참조하지 않고 해당 레이아웃에서 사용할 page 콘텐츠를 참조하게 된다. 이것은 assemble의 규칙이다.

Grunt 파일 Gruntfile.js

...
 assemble: {
      options: {
        helpers: [ 'helper/common.js' ]
      },
      build: {
        options: {
          layoutdir: 'layout',
          layout: 'default.hbs',
          partials: 'includes/*.hbs',
          data: 'data.json'
        },
        files: [{
          expand: true,
          cwd: 'docs',
          src: '*.hbs',
          dest: 'dist'
        }]
      }
...
  1. build 객체를 보면 layout/default.hbs을 레이아웃 파일로 사용한다고 한 것처럼 layoutdir과 layout에 해당 값이 저장돼 있다.
  2. 각 페이지에서 활용되는 템플릿을 저장한 partials와 데이터를 저장한 data 또한 정의돼 있다.
  3. files에는 build 객체에 저장된 정보로 {{>body}}에서 사용할 템플릿이 저장된 페이지 디렉터리를 명시하고 있다. 또한 해당 템플릿이 assemble을 이용한 Grunt 빌드를 통해 만들어지면 최종적으로 dest 값에 명시된 "dist"에 해당 결과물을 저장한다. 이 프로젝트에는 docs 디렉터리에 index.hbs라는 페이지 템플릿이 저장되어 있으므로 index.html이라는 결과물이 저장될 것이다.

페이지 정보가 저장된 docs/index.hbs

// docs/index.hbs
{{>main}}
{{>album1}}
{{>album2}}
{{>propose}}
{{>location1}}
{{>location2}}

제이쿼리 모바일은 페이지 기반의 단일 페이지 애플리케이션이다. 즉, 6개의 페이지로 이루어진 애플리케이션이다.

includes/main.hbs

...
  <h1 class="text-header"> 
  {{user.groom}} <b style="color:red"></b> {{user.brider}}  의 결혼식
  </h1>
...

{{user.groom}}은 data.json에 저장돼 있는 user 객체의 값을 참조한다.
여기서 중요한 것은 해당 템플릿의 {{user.groom}}을 변경하지 않으면 data.json의 user.groom객체의 키 값도 변경하면 안 된다는 것이다. 대신 user.groom의 value는 언제든지 변경할 수 있다.

Swipe 이벤트 처리 코드

// resources/main.js
 window.mySwipe = new Swipe( elem, {
    startSlide: 0,
    speed: 500,
    auto: 1000,
    continuous: true,
    disableScroll: false,
    stopPropagation: false,
    callback: function(index, elem) {},
    transitionEnd: function(index, elem) {}
  });
  var $slider = $( "#slider" ),
      $prev = $( "#prevButton" ),
      $next = $( "#nextButton" );
  $prev.off( "click" ).on( "click", function(){
    mySwipe.prev();
  });
  $next.off( "click" ).on( "click", function(){
    mySwipe.next();
  });

지도 페이지 API

Tmap open API 사용

// 애플리케이션 키, data.json
"application" : {
  "tmapAppKey": "59d44673-37a8-3d41-a7b6-6ca3c6ea061f"
  }

지도 연동하기

// resources/main.js
...
var initLocation = function() {
  var map = new Tmap.Map({
    div:"map1",
    width:'100%',
    height:'400px'
  });
  var markerLayer = new Tmap.Layer.Markers();
  map.addLayer( markerLayer );
  var lonlat = new Tmap.LonLat( 14127736.0000893, 4511715.2883089 );
  //var center = new Tmap.LonLat( 14123343.752289, 4512189.739492 );
  map.setCenter( lonlat, 16 );
  var size = new Tmap.Size(30,30);
  var offset = new Tmap.Pixel(-(size.w/2), -(size.h/2));
  var icon = new Tmap.Icon('./resources/img/heart.png', size, offset);
  var marker = new Tmap.Marker(lonlat, icon);
  markerLayer.addMarker(marker);
};
...
  1. initLocation은 지도를 불러오는 함수
  2. lonlat 변수에 저장되는 Tmap.LonLat()함수가 지도의 위치를 불러오게 된다. 첫 번째 인자와 두 번째 인자는 지도의 Lon 데이터와 Lat 데이터이다.

소셜 공유 마크업

// resources/js/main.js
<div>
<a href="javascript:;" id="kakao-link">
<img class="kakaolink" src="./resources/img/kakao_talk.png"
     width="100%" alt="카카오 톡으로 청첩장 보내기" />
</a>
</div>
  1. https://developers.kakao.com/
    자바스크립트 API 사용하려면 카카오에서 제공하는 자바스크립트 SDK 파일을 인클루드 해야 하며, 해당 파일은 includes/script.hbs에 선언되어 있다.
    해당 파일 다음의 자바스크립트 파일에서 초기화 코드를 작성한다.
// 카카오 연동 
ar initKakao = function(){
    /* kakao톡 링크 */
  Kakao.cleanup();
  // 사용할 앱의 Javascript 키를 설정해 주세요.
  Kakao.init('abeaf346736c57a8ba07ef2dcfcad028');
  // 카카오톡 링크 버튼을 생성합니다. 처음 한번만 호출하면 됩니다.
  Kakao.Link.createTalkLinkButton({
    container: '#kakao-link',
    label: '저희의 결혼을 축하해주세요',
    image: {
      src: 'http://dev.kazikai.net/invitation/dist/resources/img/main.png',
      width: '300',
      height: '200'
    },
    webButton: {
      text: '청첩장 바로가기',
      url: 'http://dev.kazikai.net/invitation/dist/index.html' 
      // 앱 설정의 웹 플랫폼에 등록한 도메인의 URL이어야 합니다.
    }
  });
};
...
// 카카오 연동 함수 실행
initKakao();
...

0개의 댓글