간단한 WYSIWYG Editor 만들기

회사에서 작업하다가 bold, italic, underline 기능만 필요한 WYSIWYG가 필요해서 어떻게 해야 할지 앞이 캄캄해서 그냥 오픈 소스를 써야 하나 했는데 역시 구글신이 간단한 방법을 알려줬다.

contenteditable 사용해서 엘리먼트에 바로 편집이 가능하게 된다. 요것은 HTML5 에 표준이 된거라고 하는데 브라우저 지원 여부를 확인해보니 거의 모든 브라우져에서 지원을 하고 있다. 이전에는 WYSIWYG Editor 을 만들기 위해서 iframe 과 designMode=“on” 으로 사용했다고 한다.

브라우저 지원 여부에 대해서 알아보면 다음과 같다.

"contenteditable"

사용방법은 아주아주 간단하다. 소스로 보면 다음과 같다.

WYSIWYG Editor
1
2
3
4
<div contenteditable="true"></div>
<input type="button" onclick="document.execCommand('bold', null, false);" value="B" />
<input type="button" onclick="document.execCommand('italic', null, false);" value="I" />
<input type="button" onclick="document.execCommand('underline', null, false);" value="U">

위 소스와 같이 div 엘리먼트에 contenteditable attribute 값만 주면 편집이 가능하게 되고 버튼 3개로 입력한 Text 에 바로 blod, italic, underline 효과를 줄수 있다.

그 외에 다른 execCommand 에 대한 정보는 아래 링크에서 확인 할 수 있다.

Node.js 이용해서 Chat을 만들어보자[3]

오늘은 닉네임 입력을 하고 로그인을 하고 페이지를 빠져나오게 되면 로그아웃이 되는걸 구현해 볼까 한다.

소스는 다음과 같이 수정을 하면 된다.

server.js
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
var app = require('http').createServer(handler).listen(5023)
  , io = require('socket.io').listen(app)
  , fs = require('fs')
  , nicklist = {};


function handler(req, res){
  fs.readFile(__dirname + '/index.html', function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200, { 'Content-Type': 'text/html'});
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) {
  socket.on('join', function(nick){
      nicklist[nick] = socket.nickname = nick;

      socket.broadcast.emit('joinok', nick);
      io.sockets.emit('nicknames', nicklist);
  });

  socket.on('disconnect', function(){
      delete nicklist[socket.nickname];
      socket.broadcast.emit('nicknames',nicklist);
  });
});
index.html
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JP Chat</title>
  <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  //기존 소스에서
  <form id="set-nickname">
      <label>NickName : </label><input type="text" id="nick" />
      <button id="join">Join</button>
  </form>
  <div id="nicknames"><ul></ul></div>
  <script>
      (function($){
          var socket = io.connect('localhost:5023');

          socket.on('joinok', function(nick){
              $("ul", "#nicknames").append("<li>"+nick+"</li>");
          });

          socket.on('nicknames', function(data) {
              var nicklist = $("ul", "#nicknames").empty();

              for (var i in data) {
                  $("ul", "#nicknames").append("<li>"+data[i]+"</li>");
              }
          });

          $("#join").on({
              click: function() {
                  var nick = $("#nick");
                  if (nick.val() == "") {
                      alert('NickName 을 입력해주세요.');
                      nick.focus();
                      return false;
                  } else {
                      socket.emit('join', nick.val());
                      nick.val("");
                  }

                  return false;
              }
          });
      })(jQuery);
  </script>
</body>
</html>

server.js 소스에 보면 on Method 와 emit Method가 있는데 간단하게 생각하면 된다 on Method는 받는거고 emit Method는 보내는 거다 라고 생각하면 된다.

index.html 에서 join 이라는 이벤트를 server로 요청(emit)을 하게 되면 서버에서는 join 이벤트가 실행이(on) 된다.

인자값으로 넘어온 nick 을 미리 선언된 nicklist 객체에 넣는다. 배열로 하지 않고 객체로 하는 이유는 중복을 막기 위함이다. 배열로 해도 막을 수는 있지만 막으려면 또 과정을 거쳐야 하기 때문에 간단하게 key : value 로 넣어서 같은 닉네임이 있으면 덮어 씌워지는 것이다.

또 socket.nickname 에 추가로 nick 을 넣어줘서 로그아웃 처리를 할때 사용 할 수 있게 미리 담아둔다.

이제 각 client 에게 로그인을 했다는 정보를 보내주는 과정이다. 위에 소스를 보면 두가지 이벤트를 실행하게 된다. joinok 와 nicknames 이렇게 두개를 처리하는 이유는 여러 사람에게 나 로그인 했다~ 라고 보내주는것과 또 하나는 내 화면에 나 로그인 했다~ 라고 뿌려주는 역할을 따로 따로 하기 때문이다.

여기서 broadcast 에 대한 설명은 @firejune님의 블로그에서 자세한 설명을 볼 수 있다.

Socket.IO 학습 – 퍼블릭/브로드캐스트/프라이빗 구분

이제 index.html 에서 joinok 이벤트와 nicknames 이벤트를 보면 joinok 는 기본 닉네임 리스트에 내가 쓴 닉네임을 추가 시켜주고 전체 nicknames 를 가져와서 nicklist를 다시 그려주게 된다. 전체 닉네임을 갱신한다고 생각하면 될꺼 같다.

로그아웃은 따로 로그아웃 버튼이 있는건 아니고 단지 페이지를 빠져 나가게 되면 로그아웃이라고 생각하면 될꺼 같다. 그래서 server.js 를 보게되면 disconnect 이 일어 났을때 로그인을 했을때 socket.nickname 에 넣었던 닉네임을 nicklist 객체에서 delete 해준다.

그리고 다시 socket.broadcast.emit() 로 전체 client에게 nicknames 이벤트를 호출해서 로그인 리스트를 갱신하게 된다. 그러면 로그아웃한 회원을 제외한 나머지 사람들 리스트만 보이게 된다. 여기서 왜 자신꺼는 이벤트를 호출을 안하는지 혹시 의문이 들수도 있는데 이건 생각해보면 당연한거다 내껀 페이지를 빠져 나오거나 페이지 자체를 갱신했기때문이다. 이렇게 해서 로그인, 로그아웃 구현을 끝냈다.

Node.js 이용해서 Chat을 만들어보자[2]

오늘은 socket.io를 사용해서 서버와 통신(connection, disconnection)이 어떻게 가능한지 확인해볼까 한다.

먼저 서버와의 통신을 확인하기 위해서 다음과 같이 server.js 와 index.html 소스를 수정한다.

server.js
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
var app = require('http').createServer(handler).listen(5023)
  , io = require('socket.io').listen(app)
  , fs = require('fs');


function handler(req, res){
  fs.readFile(__dirname + '/index.html', function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200, { 'Content-Type': 'text/html'});
    res.end(data);
  });
}

// 기존 소스에 이부분 추가
io.sockets.on('connection', function (socket) {
  console.log('log : in');

  socket.on('disconnect', function () {
    console.log('log : out')
  });
});
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JP Chat</title>
  <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  <form id="set-nickname">
      <label>닉네임을 입력해주세요: </label><input type="text" id="nick" />
  </form>
  <div id="nicknames"></div>
  <script>
    //socket connect script 추가
      var socket = io.connect('http://localhost:5023');
  </script>
</body>
</html>

Server, Client 소스에 socket 통신을 하기 위해서 추가된 부분이 있다 어떤 동작을 하는지 눈으로 확인해 보도록 하겠다.

socket.io 사이트에 how to use 에서 확인을 해보면 다음과 같은 부분이 있다.

Besides connect, message and disconnect, you can emit custom events

해석해 보면 connect, message, disconnect 외에도 다른 이벤트를 만들어서 사용할 수 있다는 내용이다. 기본적으로 제공되는 event 인 connect, disconnect 를 통해서 Server와 Client 사이에 통신이 가능한지 확인해보자.

socket.io 사이트에서 예제 소스를 보면 Server 와 Client가 connection이 이루어져야 socket 통신이 가능하다는걸 알 수 있다.

index.html 파일을 보게 되면 io.connect() method 에 socket 통신을 하고자 하는 Server url을 넘겨 connect event 를 호출하게 된다.

Server에서는 connection 이벤트를 호출하게 되어 함수를 호출하게 되고 터미널에는 log : in 이 찍히게 된다. disconnect 이벤트는 connect 이벤트 안에 있는걸 볼 수 있는데 이것은 단순하게 생각하면 접속을 해야 접속을 끊는 것도 가능하기 때문이라고 생각한다. 그래서 disconnect event가 발생하게 되면 터미널에 log : out 을 찍게 된다.

그럼 connection, disconnect가 이루어질때 터미널에 로그가 남는지 확인해보자.

"connect, disconnect 확인"

위 화면과 같이 index.html 에 접속했을때 log : in 을 터미널에서 확인 할 수 있고, 페이지를 나오게 되면 log : out 을 터미널에서 확인 할 수 있다.

이렇게 해서 socket.io를 통해서 Server와 Client 사이에 connection, disconnection이 이루어 지는걸 확인 할 수 있었다.

이제 Server 와 Client 사이에 socket통신이 가능 하게 되었다.

OctoverSky.js & JScamp 후기

2011년 11월 19일 토요일 하루만에 두개의 세미나를 다녀왔다.

이렇게 주말에 세미나에 다니면 집사람과 아들에게 눈치도 보이기도 하고, 몸도 힘들지만 세미나에 다녀오면 몬가 얻은 기분도 들고 여러 사람들을 만나 보면서 다른 사람들은 어떻게 자신을 발전시키고 어떤것들을 하고 있는지 볼 수 있어서 좋다고 생각한다. 그리고 동기부여(?) 같은것도 얻을 수 있어서 세미나에 자주 다니는 편이다.

이번에도 역시 몬가 해야 겠다는 생각과 함께 얻은 것들이 있었다. 그래서 나름 유익한 시간이 였다고 생각한다.

OctoberSky.js

먼저 오전에 다녀온 OctoberSky.js 라는 node.js 온라인 스터디의 첫번째 오프라인 모임이였다.

onoffmix에서 처음 알게되고 신청했을때는 대기자에 있었는데 다행이도 @doortts님께서 불편하지만 않다면 참석해도 된다고 하셔서 간신히 참석하게 되었다. 근데 당일날 확인해 보니 많은 분들이 취소를 하셔서 신청자 명단으로 올라가 있었다.

장소는 압구정 컨시어지 아카데미에서 진행되었는데 다 좋았지만 찾아가기가 좀 힘들었다. 내가 길치라서 그런건지 일찍 나오지 않았다면 한참 늦게 도착했을 것 같다.

진행 내용은 다음과 같다.

  • 간략한 발표 듣기
  • Cloud9 IDE에서의 개발 – 형주 님
  • 자바스크립트 코어 – Prototype Chain & Closure – 병주 님
  • node.js 적용 경험담 듣기 – 준호 님
  • ECMAScript 변천사 – 응준 님
  • 진행한 스터디 진도 만큼 함께 살펴보기

대략 25명정도의 인원이 모였는데 이런저런 스터디에 대한 얘기를 시작으로 자기소개를 했다ㅡㅡ;;

요즘 들어 세미나에서 자기소개를 두번째 했는데… 다른분들은 재미있게, 조리있게 말씀들을 참 잘하시는거 같다. 난 왜이렇게 떨리는지 말도 어버버 하고 말잘하는 연습좀 해야겠다 ㅋ;

이렇게 자기 소개를 맞치고 Cloud9 IDE에 대한 소개를 형주님이 해주셨다. 간단한 소개와 함께 사용방법에 대해서 설명해주시고 현재 스터디를 어떻게 작업하는 방법에 대해서 얘기해주셨다.

두번째 자바스크립트 코어에 대한 설명을 병주님이 해주셨다. 공부를 위해서 직접 발표를 신청하셨다고 한다. 정말 멋진거 같다. 난 왜 저런 자신감이 없는건지… 저런 자세는 배워야 한다!!

발표 내용은 Prorotype Chain & Closure 에 대한 정리를 해서 설명을 해주셨는데 개념을 잡기에 아주 좋은 내용을 잘 조리 있게 잘설명해주신거 같다. 알고 있는걸 다시한번 짚어 볼수 있는 시간이였다.

다음으로 이번 세미나의 최대 하이라이트 였던 준호님의 발표 시간이 였다. 내용은 node.js 사용후기? 경험담? 만들었던것들? 을 보여주시면서 재미있게 설명을 해주셨다. 정말 준호님은 대단하다는 생각이 들정도로 많은 것들을 만들어 보시고 적용해서 블로그에서 사용중이시고 멋지다는 생각이 들었다.

역시 무엇이든 만들어 봐야 배울수 있다는 생각이 든다. 이론도 이론이지만 만들어 보는거 만큼 좋은게 없다고 생각이 든 발표 였다. 다음에 꼭 FRENDS모임에 오셔서 한번더 발표해주시면 정말 좋은 시간이 될꺼 같다.

다음은 ECMAScript의 발표 였는데… 발표자분과 자리를 마련해주신분께 죄송한 마음이 들었지만… 다음 세미나 장소로 이동하였다. 나중에 들은 생각이지만 다음부턴 절대로 이런 행동은 하지 말아야 겠다는 생각이들 었다.

jscamp

이 세미나는 NHN, Daum 프론트앤드 개발자 분들이 모여서 처음 시작하게된 모임이였다. 국내 양대 포털회사 개발자 분들이 개발자로서 교류하는 모습이 좋아 보였다.

진행 내용은 다음과 같다.

  • 컨퍼런스 개회 및 소개 박재성(NHN)
  • 우리 회사 이야기, 우리 회사 개발 이야기 송승렬(NHN), 유경민(Daum)
  • Titanium – javascript 이용한 크로스플랫폼 App개발 이종은(Daum)
  • node.js 가 뭐야? 먹는거야? 손병대(NHN)
  • 웹 기반 하이퍼포먼스 그래픽 처리 문경두(Daum)
  • Hudson 과 Selenium을 이용한 QUnit 테스트 자동화 김민종(NHN)
  • 즉석 질의 응답, 무엇이든 물어보세요!

조금 늦게 도착해서 컨퍼런스 개회 및 소개는 잘 듣지 못했다.

우리 회사 이야기, 우리 회사 개발 이야기 회사 개발방식에 대한 내용이 였다. 다른 회사들은 저런 방식으로 개발을 하는구나 라는걸 볼수 있어서 나름 괜찮았다. 한편으로는 불필요한 내용인거 같기도 했다.

Titanium 발표는 생각지도 않은 부분이 였지만 발표자분께서 살짝 라이브 코딩을 보여주시면서 Titanium에 대한 장점들을 보여주시고 앞으로 어떻게 발전해 나갈것인지 어떤점들이 좋은지 단점은 어떤것들이 있는지 잘 설명해주신거 같다. 개인적인 생각으로 전체 발표중에서 제일 좋았다고 생각한다.

역시 발표하는 사람은 유머러스한 면이 있어야 많은 사람들이 좋아하는거 같다.

node.js 에대한 얘기를 그냥 node.js를 아는 사람에게는 그닥 불필요한 내용이 였다 하지만 node.js 무엇인지 처음 들어본 분들에게는 아~ 이런 기술이 있구나 하고 알게 되고 사용해볼 생각을 같게될수 있는 발표 였다고 생각한다.

웹 기반 하이퍼포먼스 그래픽 처리 canvas, webGL, css에 대한 그래픽 처리에 대한 발표 였다. 발표자 분이 응근 재미있게 발표해 주셔서 나름 재미있는 발표 였다고 생각한다. 예제를 보여 주셨던것이 좋았던거 같다. 개인적으로 canvas, webGL보단 css 부분이 내가 사용해 보기엔 좋은것들이 였다고 생각한다.

Hudson, SElenium 을 이용한 Qunit테스트 자동화 사실 이 발표가 제일 기대 되고 꼭 듣고 싶었었다. 항상 테스트에 대한 내용을 접하게 되면 느끼는 거지만 저것들은 왜 구지 저렇게 하는 것일까? 라는 생각을 했었다. 하지만 자동화를 통해서 사용을 한다면 테스트는 좋은 부분들이 많을거 같다. 일단 어떤 방법이 있는지 알았으니 찾아보고 적용해 보는건 내 몫이라고 생각한다. 좀더 검색해보고 테스트 해봐야 할 부분인거 같다.

이렇게 해서 두번째 세미나도 끝이 났다.

힘들 하루 였지만 얻는것도 많은 하루 였다. 우리 FRENDS 에서도 이런 세미나가 빠른 시일에 이루어 지면 재미있을꺼 같다.

Node.js 이용해서 Chat을 만들어보자[1]

그동안 node.js 에 대해서 맨날 보기만 하다가 H3 채팅을 보고 직접 만들어 보고 싶다는 생각이 들었다. 그래서 간단한 채팅을 만들어 볼려고 한다.

오늘은 기본적인 web server 구동을 시작해보겠다. 아래 소스는 github Repositorie에 올리면서 진행하려고 한다. nodester에서 호스팅을 받아서 nodester쪽에서도 확인해볼수 있다.

먼저 채팅을 만들기 위해서 기본적으로 socket 통신을 해야 하므로 npm을 이용해서 socket.io를 설치했다.

npm install
1
$ npm install socket.io

socket.io를 설치하면 examples 디렉토리 안에 chat이 있는데 express 이외에도 많은 모듈을 사용해서 만들어져있다. 나는 단순한 socket 통신을 하는거만 보기 위한거라서 다른 모듈 없이 socket.io 만 사용해서 만들어 볼려고 한다. 소스는 socket.io/examples/chat 소스를 바탕으로 작업을 했다.

우선 가장 기본적인 부분인 Web Server 구현해 볼려고한다.

필요한 파일은 서버쪽 server.js 파일과 클라이언트 페이지 index.html 이 필요하다.

Server.js

서버쪽에서 Web Server가 구동되야 하므로 server.js 에 다음을 추가한다.

server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var app = require('http').createServer(handler).listen(5023)
  , io = require('socket.io').listen(app)
  , fs = require('fs');


function handler(req, res){
  fs.readFile(__dirname + '/index.html', function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200, { 'Content-Type': 'text/html'});
    res.end(data);
  });
}

대략 소스를 보면 http, socket.io, fs 모듈을 사용하고 있다.

여기서 http 모듈은 서버를 생성할때 handler 함수를 인자값으로 넘겨줘서 서버를 Web Server 를 생성하고 port 5023(port 번호는 마음대로 설정해도 된다) 으로 접근할수 있게 설정했다.

handler 함수는 예전부터 가장 궁금했던 부분중에 하나인 html 파일을 어떻게 보여주는지 궁금했었는데 그부분을 구현한 함수 부분이다. fs 모듈을 이용해서 index.html 파일을 읽어서 보여주게 된다.

파일을 읽는중 문제가 생기게 되면 다음과 같이 500 에러가 발생하고 메시지를 보여주게 된다.

"500 err"

handler 함수에서 fs.readFiel() method 에 index.html 파일을 인자값으로 넘겨줄때 __dirname 이 있는데 nodejs doc에서 확인을 해보면 __dirname 은 node.js의 global Object로 현재 스크립트파일의 위치를 담고 있는 객체인걸 알 수 있다.

socket.io 모듈은 listen Method는 인자값으로 http 모듈을 담고 있는 app 변수를 넘겨준다. 나름 해석해보면 socket.io 가 Web Server를 항상 듣고 있는 모 그런거 같다 ㅋ;;.

index.html

server.js 에서 index.html을 읽어들여서 보여주기 위해서 index.html 에 간단한 닉네임 입력창을 넣어준다.

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JP Chat</title>
  <script src="http://code.jquery.com/jquery-1.7.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  <form id="set-nickname">
      <label>닉네임을 입력해주세요: </label><input type="text" id="nick" />
  </form>
  <div id="nicknames"></div>
</body>
</html>

클라이언트에서도 jQuery & socket.io를 쓰기위해서 jquery-1.7.min.js 와 socket.io.js 를 추가해 주었다.

그러면 Web Server가 잘 동작하는지 확인해 보자. 터미널에서 다음과 같이 서버를 시작하고 브라우져에서 확인해보자.

"server"

브라우져에서 확인해보면 다음과 같이 input 박스를 확인할수 있다.

"client"

다음엔 닉네임 입력을 하고 채팅방에 join 하는 것을 구현해 보겠다.

Octopress Posting 하기

국내에 이외로 많은 분들이 Octopress를 써보고자 하는거 같다.

그래서 이전에 설치하는 방법만 올렸었는데 간단하게 Octopress로 Posting하는 방법을 써볼까 한다.

먼저 간단한 Posting하는 방법에 대해서 알아보자.

Posting하는 과정을 간단하게 쭉 말해보면 rake new_post[제목] 명령어로 markdown 파일을 만들어서 내용을 작성하고 rake generate 명령어로 html 파일을 만들어서 rake preview 명령어로 작성된 post를 로컬에서 확인하고 rake deploy 명령어로 github에 올린다.

이게 전부이다.

자 그러면 하나씩 알아보자.

1. rake new_post[제목]

작성하고자 하는 post가 있다면 먼저 작성하고자 하는 페이지를 만들어야 한다. 나도 markdown 을 써본적이 없었지만 octopress를 사용하게 되면서 알게 되었다. 근데 워낙 사용방법 자체가 쉽기 때문에 따로 배울 필요없이 쓰다보면 자연스럽게 알게 되는거 같다.

터미널에서 다음과 같이 명령어를 입력하면 markdown 파일이 생성된다.

Markdown 파일 생성
1
$ rake new_post["쓰려고 하는 post 제목"]

위와 같이 터미널에서 입력하고 나면 octorpess/source/posts/ 경로에 오늘 날짜와 입력한 제목이 조합된 이름으로 생성된 markdown 파일을 확인 할 수 있다. 날짜는 나중에 generate 해주면 octopress/deploy/blog 안에 파일을 생성할때 날짜 부분을 가지고 디렉토리를 생성하기 위해서 필요한듯 하다.

이렇게 파일이 생성되면 이제 octorpess/source/_posts/ 경로로 가서 markdown 파일을 열어서 post를 작성하면 되는데 파일을 열어보게 되면 다음과 같은 내용이 미리 들어가 있다.

Markdown 파일 내용
1
2
3
4
5
6
7
---
layout: post
title: "쓰려고 하는 post 제목"
date: 2011-11-14 09:19
comments: true
categories:
---

레이아웃, 제목, 날짜, 댓글, 카테고리 설정부분 이다. 처음 파일 생성할때 썼던 제목이 들어가 있는데 이부분은 변경하면 post제목은 변경 할 수 있다. 또 날짜도 변경할수 있고 댓글 유무도 변경할수 있고 카테고리는 태그 같은 것인데 입력하는 방법이 몇가지가 있는데 방법은 다음과 같다.

Categories 작성 방법
1
2
3
4
5
6
7
8
9
10
11
// 하나의 category 작성방법
categories: cate1

// 두번째 여러개 category 작성방법1
categories: [cate1, cate2, cate3]

// 세번째 여러개 category 작성방법2
categories:
- cate1
- cate2
- cate3

위와 같이 세가지 category 작성방법이 있다. category는 post 하단부분에 다음과 같이 표시된다.

"category" 그냥 마음대로 사용하기 편한걸 선택해서 사용하면 될꺼 같다. 이제 작성하고자 하는 post를 작성하면 된다.

2. rake generate

작성한 post를 html로 만들어주는 과정이다. 터미널에서 다음과 같이 입력해주면 된다.

Post generate
1
2
3
4
5
6
$ rake generate
Generating Site with Jekyll
unchanged sass/screen.scss
Configuration from /Users/jjp5023/octopress/_config.yml
Building site: source -> public
Successfully generated site: source -> public

위와 같이 입력하면 config.yml 있는 설정을 적용하고, source 안에 있는 markdown 파일을 html로 변경하고, sass 를 css파일로 변경되는 작업이 일어난다. generate 된 것들은 octopress/deploy 안에 들어가게 된다.

3. rake preview

octopress는 로컬에서 작성을 해서 github에 올리는 방식이다. 서버에 올리기전에 내가 작성한 post가 어떻게 보이는지 당연히 궁금하다. 그래서 로컬에서 미리보기가 가능하다.

Post 미리보기
1
2
3
4
5
6
7
8
9
$ rake preview
Starting to watch source with Jekyll and Compass. Starting Rack on port 4000
Configuration from /Users/jjp5023/octopress/_config.yml
[2011-11-14 10:21:11] INFO  WEBrick 1.3.1
[2011-11-14 10:21:11] INFO  ruby 1.9.2 (2011-07-09) [x86_64-darwin11.0.1]
[2011-11-14 10:21:11] INFO  WEBrick::HTTPServer#start: pid=10385 port=4000
Auto-regenerating enabled: source -> public
[2011-11-14 10:21:11] regeneration: 505 files changed
>>> Compass is watching for changes. Press Ctrl-C to Stop.

터미널에서 위와 같은 입력하면 여러 메시지와 함께 서버가 시작되고 http://localhost:4000 에서 확인 할 수 있게 된다. 서버를 멈추기 위해선 Ctrl + C 명령을 사용하면 된다.

4. rake deploy

이제 모든 posting 과정이 끝났다 이제 github 서버에 올리기만 하면 진짜로 posting이 끝나게 된다. 다음과 같이 입력 한다.

Post 올리기
1
$ rake deploy

위와 같이 입력을 하면 github에 octopress/_deploy 안에 있는 파일들이 push가 되어서 github에 올라가게 된다. 여기서 push 란 git 명령어 인데 그냥 말그대로 서버에 밀어넣는 것을 말한다. 이렇게 하면 하나의 post를 작성해서 서버에 올리는 과정이 끝나게 된다.

내 생각이지만 git을 잘 알지 못하여도 git push 개념만 알고 있다면 구지 git을 몰라도 octopress로 블로깅을 하는데 전혀 지장이 없다고 생각한다. 기억할껀 위 과정 하고 github에 올라가는 파일들은 octopress/_deploy 안에 있는 파일들이 라는 것인거 같다…

Goclipse 설치

그동안 컴파일 언어를 제대로 사용해보지 않아서 인지 Go 언어를 공부하는데 컴파일 하는 부분이 나한테는 불편한 일이다. 그래서 IDE를 찾아보니 Goclipse라는 Eclipse에 plugin을 설치해서 사용하는 것이 있었다.

그래서 간단하게 설치하고 사용하는 방법에 대해서 작성해 볼까 한다.

Eclipse 설치

Eclipse 에 Plugin 을 설치해서 사용하는 것이기 때문에 먼저 Eclipse가 설치 되어 있어야 한다.

Eclipse 이곳 에서 3.6 혹은 이상의 버전을 받아서 설치를 한다.

Goclipse plugin 설치

Eclipse 실행하고 Help > Install New Sofeware 를 선택한다. Work with 박스에 다음 URL을 입력하고 Add 버튼을 눌러서 Go Repository를 추가해다.

Goclipse plugin
1
http://goclipse.googlecode.com/svn/trunk/goclipse-update-site/

쭉 설치를 진행하시고 Eclipse를 다시 시작한다.

환경설정 창을 열어서 Go 메뉴에서 PATH를 설정해준다. PATHA는 설치할때 설정한 .bash_profile 내용을 참고해서 설정한다.

"goclipse 환경설정"

Hello World 실행

Hello World 코드를 작성하고 터미널에서 컴파일 작업을 따로 할 필요없이 Eclipse에서 Run 해서 Eclipse Console 창에서 결과를 볼수 있다.

"goclipse 환경설정"

참고 URL

Go

Start Go Language

Go[for]it 세미나에 다녀온 후로 Go 언어에 관심이 가기 시작했다.

그동안 컴파일 언어를 제대로 공부해본적이 없어서 인지 재미도 있는거 같고 스크립트 언어와 또다른 재미가 있는거 같다.

Go[for]it 세미나에 가기전에 MBA에서 제대로 PATH설정 문제로 인해서 컴파일이 제대로 되지 않았는데 세미나에 다녀온 후로는 신기하게도 PATH설정 문제도 해결되고 Goclipse 를 알게 되어서 좀더 편하게 공부 할 수 있게 되었다. 그래서 일단 기본인 설치부터 Goclipse 설정까지 정리해보고 Hello World까지 정리해 볼까 한다.

Go 설치

현재 MAC을 쓰고 있기 때문에 MAC 기준으로 설명을 하겠다. 우선 저장소에서 Go를 받아 와야 한다. 그러기 위해서는 Mercurial 이 필요하다.

hg 명령이 동작하는지 확인하고 만약 동작하지 않는다면 다음과 같은 명령으로 설치 하면 된다.

Mercurial Install
1
$ sudo easy_install mercurial

혹 위 과정이 진행이 되지 않는다면 python, setuptools이 설치가 안되어 있을수도 있다. python, setuptools 설치 과정을 먼저 진행하시면 됩니다.

위에서 easy_install 은 python에서 사용되는 패키지 관리해주는 파이썬 모듈이라고 한다.

저장소에서 가져오기

이제 mercurial을 통해서 다음과 같이 실행하면 저장소에서 있는 소스를 go 디렉토리에 가져오게 된다.

Go clone
1
$ hg clone -u release https://go.googlecode.com/hg/ go

PATH설정

빌드를 진행하기전에 PATH설정을 먼저 하는것이 좋은거 같다. 처음 아무것도 모르고 설치를 진행 했을때 제대로 go 컴파일이 안되었던것이 PATH문제 였는데 검색을 해서 보고, all.bash 파일을 열어보면 빌드과정 소스에 PATH를 통해서 진행되는걸 확인 할 수 있다. 그래서 빌드 하기전에 다음과 같이 PATH를 먼저 설정한다.

1
2
3
4
5
export GOROOT=$HOME/go
export GOOS=darwin
export GOARCH=386
export GOBIN=$HOME/go/bin
export PATH=$PATH:$HOME/go/bin

각 PATH에 관한 설명은 다음과 같다.

  • GOROOT

Go 트리에서 루트는 $HOME/go. 해당 디렉토리의 부모 디렉토리를 기본으로 하며 all.bash가 실행되는 디렉토리다. $GOROOT를 설정하지 않으면 makefile을 이용해서 Go 프로그램을 개발할 때 반드시 make나 gmake 대신에 gomake를 실행해야 한다.

  • $GOOS 와 $GOARCH

타겟 운영체제의 이름과 컴파일 구조. $GOHOSTOS와 $GOHOSTARCH 값들을 기본으로 한다. $GOOS는 리눅스, freebsd, darwin(맥 OS X 10.5 혹은 10.6), 윈도우(작업중). $GOARCH는 amd64(64-bit x86, 현재 가장 완성도 높음), 386(32-bit x86) 그리고 arm(32-bit ARM, 작업중). $GOOS와 $GOARCH의 사용가능한 조합은 다음과 같다. $GOOS $GOARCH 비고 darwin 386 darwin amd64 freebsd 386 freebsd amd64 linux 386 linux amd64 linux arm 작업중 windows 386 작업중

  • $GOBIN

바이너리가 설치된 위치. 기본값은 $GOROOT/bin이다. 설치 후, 해당 디렉토리를 $PATH에 추가하여 Go가 제공하는 여러 도구들을 사용할 수 있다.

Go 설치

다음과 같이 진행 하면 된다.

Go Install
1
2
$ cd go/src
$ ./all.bash

모든 것이 잘 진행되면 다음과 같은 출력이 나온다.

Go Install
1
2
3
4
5
6
7
8
9
10
ALL TESTS PASSED

---
Installed Go for darwin/386 in /Users/jjp5023/go.
Installed commands in /Users/jjp5023/go/bin.
*** You need to add /Users/jjp5023/go/bin to your $PATH. ***
The compiler is 8g.

On OS X the debuggers must be installed setgrp procmod.
Read and run ./sudo.bash to install the debuggers.

Hello World

이제 설치가 끝났다. 모든 언어의 기초 Hello World를 찍어보자. 다음과 같은 코드를 작성해서 hello.go 를 만들어 보자.

Go Hello World
1
2
3
4
5
6
7
package main

import "fmt"

func main() {
  fmt.Printf("Helllo, World\n")
}

위와 같이 작성한 후 컴파일을 다음과 같이 진행합니다.

Go Hello World
1
2
3
4
$ 8g hello.go
$ 8l hello.8
$ ./8.out
Hello, World

위와 같이 Hello, World 가 찍힌것을 보았다면 이제 부터 본격적인 Go언어 공부를 할 준비는 끝났다.

Go 릴리즈 버전 관리

Go 는 아직도 개발중인 언어이기 때문에 자주 release 된다. Go install 페이지 보면 다음과 같은 내용이 있다.

Mercurial 저장소에 release와 weekly라는 2개의 고정테그를 관리하고 있다. weekly 테그는 매주 한 번씩 갱신되고 프로젝트 개발을 경과를 추적하기를 원하는 경우 사용한다. release 테그는 빈번하지는 않고 weekly 테그 중에 안정성이 검증된 것에 사용한다.

대부분 Go 사용자들은 최신 release 테그를 가진 Go를 설치하고 싶어할 것이다. 새로운 릴리즈는 golang-announce 메일링 리스트를 통해 공지한다.

그래서 현재 Go 를 최신 릴리즈로 갱신 하려면 다음과 같이 진행하면 된다.

Go Update
1
2
3
4
$ cd go/src
$ hg pull
$ hg update release
$ ./all.bash

이렇게 해서 Go 설치와 실행, 업데이트 하는 방법까지 알아봤다.

Go

Go[for]it 세미나 후기

"golang"

먼저 신제용, 김종민 두 분께 발표하느라 고생하셨다는 말과 좋은 자리 마련해주신 권순선님께 감사의 말씀을 전해 드리고 싶다.

업무나 관심에 있어서 주언어는 Javascript이지만 나는 왠지 다른 언어에도 관심이 간다. 다른 언어들의 문법은 어떤지 또 Javascript랑은 어떤 부분에서 어떤 차이가 있는지 등 요런 부분에 관심을 가지고 있어서 Go Lang 세미나에 참석하게 되었다.

Hellow Wolrd라도 돌려보고 참석하려고 했으나 PATH설정 문제로 컴파일이 잘 되지 않아서 예제 하나 돌려보지 못하고 참석하게 되었다.

세미나는 구글 코리아에서 이루어 졌다. 처음 가봤는데 음료수를 마음껏 먹을 수 있다는 점에서 아주 만족스러웠다 ㅋ;

첫 강사님의 발표는 Go언어에 대한 역사와 어디에 사용되는지등 Go언어에 대한 소개 시간이 였다. Go언어는 마치 예전에 NBA팀 시카고 불스의 전성기 때 처럼 Go언어는 최고의 드림팀이 만들었다고 한다. 소개를 보니 5명의 어마어마한 사람들이 모여서 만든듯 하다. 그 외에도 쓸수 있는곳 정식서버스, 역사 등 Go언어에 대해서 소개를 해주셨다. (자세한 내용은 밑에 대충;;)

두번째 강사님은 실질적인 문법과 예제를 통해서 Go언어에 대해서 알려주셨다. 처음에는 이해 할 수 있었지만 Java, C, C++를 제대로 해보지 않은 터라 후반 부로 갈 수록 이해 못하는 용어들, 개념들이 나와서 좀 어려웠지만 얼추 어떤 내용인지는 감은 잡을 수 있었다.
무엇 보다 예제로 보여주신 url단축 서비스는 간단한 소스로 그런 서비스를 만들 수 있다는 것 만으로도 관심을 가지게 만들었다. 또 써보지는 않았지만 Google App Engine 에서 Go언어를 사용 할 수 있다는 점에서 웹 개발을 할 때도 유용하게 쓸수 있지 않을까 하는 생각이 들었다. 그리고 Go언어는 소스가 직관적이고 문법들이 쉬운거 같아서 배우기 쉬운 언어 인 같다.

새로운 사람들 여러가지 언어를 접하고 관심있는 사람들 정말 재밌었던 분위기와 모임이였다. 앞으로 계속 적으로 이 모임에 참석하고 싶어 졌다.

아래는 참고 사이트와 Go 언어 소개에서 나왔던 부분들이다.
설명듣느라 전부를 받아 적지는 못했지만 한국어로 번역된 곳에 가면 거의 모든게 번역 되어 있는거 같다. 공부할때는 이곳을 참고 하면 좋을꺼 같다.

Go Lang 관련 한국 사이트

이런 곳에 써바

  • Web Server
  • Web browsers
  • Web crawlers
  • Search indexers
  • Compilers
  • Programeing tools
  • IDEs
  • OS

정식서비스

  • Google App Engine
  • Gcc 4.6.0 포함
  • 내년 초 Go version 1
  • Android (?)
  • Chrome (?)

Go 시작

  • 2007년 9월
  • Robert Griesemer, Ken Thompson and Rob Pike

형태 구성

  • 2008년 중반
  • 설계가 대략 되었고 이제 구현(컴파일러, 런타임)

인력보강

  • Ian Lance Taylor and Russ Cox

도구

  • gomake
  • goinstall – 패키지 시스템
  • godoc – 로컬에서 go 문서를 볼 수 있는 도구
  • gofix – 버전 바뀌었을 때를 위해 프로그래머를 보조하는 도구.
  • gofmt – 코딩 컨벤션을 맞춰주는 시스템
  • gotest – 단위 테스트.
Go

Javascript에서 This란 무엇인가?

Javascript를 개발할때 사용하거나 공부를 할때 해깔리고 어려운 부분중에 하나인 this에 대해서 내가 아는 부분을 정리해 볼까 한다.

나 또한 this에 대해서 많은 부분 해깔려 하던중 FRENDS의 AJ(@andrwj)의 강의를 듣고 확실한 개념을 잡을 수 있었다.

AJ(@andrwj)가 말하는 this는 아주 간단했다. 한마디로 정의 하면 다음과 같다.

  • Method를 호출한 녀석
  • 쩜(.) 앞에 녀석

그래도 몬지 잘 모를 수도 있고 오!! 라고 하며 감탄사를 내 뱉을 수도 있다. 지금 부터 예제를 통해서 this 에 대해서 알아보자.

먼저 함수 몸체에서 사용되는 this 를 알아보자. 내가 처음 this 에 대해서 알게 되었을때 제대로 알지 못하고 함수 안에서 사용하게 되면 그 함수의 property가 되는줄 알고 사용 했던 적이 있다. 하지만 확인을 해보면 함수 몸체에서 사용한 this는 window 를 갈이 키는 것이다.

다음 소스코드를 확인해보자.

Function in this
1
2
3
4
5
6
7
function J2PFn(){
  this.J2PName = "J2P";
}

J2PFn();

console.dir(window); //콘솔창에서 확인

window method 에 window.J2PFn 이 있는것을 확인 할 수 있다. 어라? 근데 window.J2PName 도 같이 있다. 보통 생각했던 결과는 J2PFn 함수 안에서 this가 갈이키는 것은 당연히 함수자신(J2PFn)라고 생각을 한다.

함수를 실행 할때 J2PFn(); 이렇게 실행을 한다. 하지만 결국 이것은 window.J2PFn() 하는것과 마찬가지 인 것이다. 그렇다면 처음에 정의했던데로 생각해보자.

“Method를 호출한 녀석” 즉 J2PFn() 을 호출한 window 가 되는것이고 또 “쩜 앞에 녀석” .J2PFn() 앞에 있는 window가 되는것이다.

이제 두번째 예제를 보자. 함수의 몸체에 사용하는것은 위에 예제와 똑같다. 하지만 new 연산자로 객체를 생성하였다. 객체를 생성하게 되면 함수 몸체에 있던 this 는 인스턴스된 객체에 property 가 된다. 그래서 처음에 우리가 생각했던 J2PObj.J2PName 으로 접근이 가능하게 된다.

다음 소스코드를 확인해보자.

Function in this
1
2
3
4
5
6
7
function J2PFn(){
  this.J2PName = "J2P";
}

var J2PObj = new J2PFn();

console.dir(J2PObj); //콘솔창에서 확인

처음 우리가 생각했던 this가 바로 요런것이 였을것이다.

위 2개의 예제에서 볼 수 있듯이 함수 안에서 사용되는 this는 인스턴스가 되지 않으면 우리가 생각했던 this가 되지 않는 것이다.

이제 세번째 예제를 보자. 세번째 예제는 Element 에서 이벤트를 발생할때 사용되는 this 이다. 어쩌면 이것이 가장 많이 사용되는지도 모르겠다.

다음 소스코드를 확인해보자.

Element in this
1
<img src="img.gif" alt="photo" onclick="J2PFn(this);" onmouseover="J2PFn2(this.src)" />

click 이벤트가 발생한 경우 함수를 호출 할때 this를 인자 값으로 넘겨주는 경우가 있을것이다. 또 mouseover 이벤트가 발생할 경우에도 image의 src를 변경해서 이미지를 변경시키는 경우에도 this.src라는 값일 인자로 넘겨주기도 할 것이다.

그렇다면 여기서 this는 무엇인가? 요부분을 해깔려 하는 경우가 있을 것이다. 자세히 보면 정말 간단하다. click 이벤트나 mouseover 이벤트는 img가 호출을 시킨것이다. 그리고 이벤트를 element에 써주지 않고 따로 스크립트에서 처리는 한다면 더 명확하게 알 수 있다. 다음 소스를 보자.

Element in this
1
2
3
4
5
6
7
8
9
10
11
12
13
<a id="blog-link" href="http://j2p.kr">J2P</a>

<script type="text/javascript">
  document.getElementById("blog-link").onclick = function(){
      console.log(this);

      return false;
  }

  document.getElementById("blog-link").addEventListener("mouseover", function(){
      console.log(this);
  }, false);
</script>

이제 처음에 말했다 this의 정의 대로 해석해 보자.

“Method를 호출한 녀석” onclick를 호출한 녀석이 누구인가? 바로 blog-link 아이디 값을 가지고 있는 Element a 태그이다.

쩜(.) 앞에 녀석 .onclick 앞에 있는 녀석은 누구인가? document.getElementById(“blog-link”) 이다.

소스코드에서 두번쨰 addEventListener 땜에 해깔릴수도 있을거 같은데 결국 저것도 mouseover 이벤트를 걸어주는것이기 때문에 mouseover 이벤트가 실행될때를 생각해보면 this 정의한 것으로 생각해보면 똑같은 결과가 나온다.

이렇게 this에 대한 설명이 끝났다 사실 경우가 더 있지만 위에 3가지 정도만 알고 있다면 다른 this를 의해는데는 그렇게 크게 어렵지 않을꺼라 생각한다. 무엇보다 가장 쉬운 방법은 console.log 찍어보는 눈으로 확인하는것이라고 생각한다.