Meteor Up 삽질기

Meteor Deployment 검색해보면 모든 예제가 전부 Ubuntu였음.
개인적으로 서버는 항상 Debian을 선호해서 찜찜하지만 ‘Debian이나 Ubuntu나~’하면서 Debian 강행.
배포 안됨.

Debian이라서 문제인건지.
apt로 mongodb를 설치해서 문제인건지
nvm으로 node를 잡아놔서 문제인건지..
mup 계속 실패. deb-mup(데비안용 mup)또한 마찬가지.
설정 바꾸며 삽질해도 안됨.
5초 설정 바꾸고 배포 결과 떨어지는데 5분~10분..
결국 모든 설정과 의심되는 부분 다 작업해도 안됨.
이것때문에 반나절 날림.
큰맘먹고 Ubuntu로 바꿈.
정말 한.번.에됨.

결론.
Meteor Server는 Ubuntu를 쓰자 -ㅅ-;

광고

Javascript로 링크 및 AJAX구현시 Fallback Link를 제공해야 하는 이유

f1e4ccf2bb4122e22aba7f35653d5494

Javascript로 행해지는 Action의 결과물이 서버(Server)로 요청(Request)하는 행위라면 Fallback Link를 함께 제공해주는것이 안전하다.

서버로 요청한다는것은, 단순히 UI를 위한 스크립트가 아니라는 말이다.
즉 페이지 이동 하거나, 값을 전송하기 위함인데
필자는 단순히 UI변경하는것보다, 서버로 값을 전송하는게 더 비중있는 일이라고 생각한다.
그 이유는 대다수의 경우 서버로 값을 전송하는것이 Action의 Goal인 경우가 많기 때문이다.
그러므로 난 Fallback Link를 제공해야 한다고 주장하는 것이다.

예를들어
로그인 버튼을 누를시 Javascript를 이용해 서버에 값을 전송하는 환경이라고 하자.
근데 어떠한 이유에 의해서 Javascript가 동작을 안한다면
이 유저는 로그인을 할 수 없게 되는것이다.

자, 그럼 Fallback Link는 무엇이냐?
아주 간단하다. javascript로 동작하는 a태그의 href에 유효한 url을 입력하는 것이다.
그러므로 Click 이벤트가 일어나는 모든것은 Clickable한 객체로 마크업을 하는것이 바람직하다.

Fallback Link는 언제 동작하는것이냐?
이것 또한 간단하다. Javascript가 동작하지 않는 상황을 대비하는것이다.

근데 솔직히 말하면 브라우저가 자바스크립트를 지원하지 않아서, 자바스크립트가 미구동되는 경우는 거의 없다.
하지만 자바스크립트 문법 에러가 나서 동작하지 않는 경우는 꽤 있으므로, 이에 대한 대비로 봐도 된다.
뭐 사실 갖다붙이면 여러가지 이유가 있겠지만..
결론적으로 말하면 자바스크립트 미구동에 대비하는걸로 인해 생기는 부수적인 효과들이다.

돌아와서 Fallback Link제공의 간단한 예를들면

<a onclick="like('comment', 1)" href="#">Like</a>

이렇게 된걸 아래와 같이 수정하는것이다.

<a href="/like" data-action="like" data-content-type="comment" data-content-id="1">Lik</a>

$("a[data-action='like']").click(function(e) {
    # do something
});

단순히 Fallback url을 제공했다고 끝나는게 아닌다.
해당 url이 실제로 동작을 해야 한다.

서버단에서 요청된 Header정보를 보고 Ajax인지 아닌지 판단하고,
여부에 따라서 응답을 달리 해주는 작업을 해줘야 한다.

무슨말인고하니,
보통의 경우 Ajax 응답만 작업했을것이고, 해당 코드는 아래와 같을것이다.

$("a[data-action='like'][data-content-type='comment'][data-content-id='1']").addClass("selected")

하지만, url을 타고 요청이 왔을 경우 유저는 하얀 화면 혹은 위 JS코드가 출력된(?) 화면을 보게 될 것이다.
이럴경우를 대비해야 한다는것이다.

기획단에서 어떤 페이지로 렌딩(Landing)할 것 인지, 먼저 정한 다음
해당 페이지를 렌더링(Rendering) 혹은 리다이렉트(ReDirect)해주면 된다.

Rails에서는 그냥 몇글자 추가해주면 되지만..
보편적인(?) PHP로 예를들면

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    // Ajax Process
}
else {
    // Page Redirect
}

이 정도?
PHP 코드 출처: http://davidwalsh.name/detect-ajax

사실 이런 내용은
Graceful Degradation, Unobtrusive Javascript
같은 방법론들이 얘기하는것과 일맥상통하기도 한다.

탭메뉴는 어떻게 코딩 해야 할까?

우선 먼저 말하고 싶은것은 내가 적은 방법이 정답은 아니다.
정수 ‘2’ 라는 값을 만들기 위해서

  • 1+1
  • 2/8*((16-4)/3)*2
  • sin 5/6 pi * 4

같은 많은 식들이 존재하듯이, 아래에 나온 방법도 그중 하나 일 뿐이다.

별 내용없는 두서는 이제 접기로 하고…

  • semantic markup
  • CSS가 없을때도 제대로 보이도록
  • Javascript가 동작하지 않을때도 동작하도록

위의 사항들을 고려하며 코딩되었다.

<menu id=”tab_menus”>
<li><a href=”#Menu_01″>Menu 01</a></li>
<li><a href=”#Menu_02″>Menu 02</a></li>
<li><a href=”#Menu_03″>Menu 03</a></li>
</menu>
<div></div>

<div id=”Menu_01″>
<h3>Menu 01</h3>
<p>Menu 01…blablablablabla</p>
<a href=”#tab_menus”><img src=”btn_top.gif” alt=”go tab menu” /></a>
</div>
<div id=”Menu_02″>
<h3>Menu 02</h3>
<p>Menu 02…blablablablabla</p>
<a href=”#tab_menus”><img src=”btn_top.gif” alt=”go tab menu” /></a>
</div>
<div id=”Menu_03″>
<h3>Menu 03</h3>
<p>Menu 03…blablablablabla</p>
<a href=”#tab_menus”><img src=”btn_top.gif” alt=”go tab menu” /></a>
</div>

tab menu 의 링크를 각각의 content에 걸어줌으로 인해 quick link의 역활을 수행하여 접근성을 높였고, 각 content 하단에 tab menu로 바로 가는 quick link도 제공함으로 더욱 완성도 높은 접근성이 보장되었다. 하지만 이렇게 보면 전혀 tab menu같지가 않다.

이제는 tab menu스럽게 꾸며보자.

body {
font:12px arial;
}
a {
text-decoration:none;
}
img {
border:0;
}

/* tab menu */
#tab_menus {
margin:0;
padding:0;
list-style:none;
}
#tab_menus li {
margin-bottom:16px;
float:left;
padding:0px;
}
#tab_menus li a {
padding:8px 10px;
color:#505050;
border-width:1px 0 1px 1px;
border-style:solid;
border-color:#ae9f96;
background-color:#eae4e0;
background-image:none;
font-weight:bold;
font-size:0.9em;
display:block;
}
#tab_menus li a:hover {
color:black;
}
#tab_menus li.selected a {
border-bottom:0 solid white;
background:white url(“blt_arrowdown.gif”) no-repeat center bottom;
color:black;
}
.tab_right {
margin-bottom:16px;
border-width:0 0 1px 1px;
border-style:solid;
border-color:#ae9f96;
width:80px;
height:31px;
float:left;
}

/* content */
.content {
clear:both;
padding-left:10px;
}
.content h3 {
margin:0;
padding:0;
font-size:1.2em;
color:#ff4800;
}

tab menu의 a를 block으로 잡고 hover를 주어 onMouse상태일때 Javascript없이도 변화를 줄 수 있게 하였다.
#Menu_02, #Menu_03에 display:none을 안 준 것을 궁금해 하는 독자가 있다면, 당신은 천재!
Javascript없이도 모든 content의 접근성을 보장하기 위해서다. 이건 조금 후 다시 설명하기로 하고..

자 이제는 마무리. Javascript로 tab menu 동작을 만들자.
mootools 1.11(Element.Event, Element.Selectors)을 이용하였다

var selected_menu = 0;
var menus = $$(‘#tab_menus li’);
var contents = $$(‘div.content’);
contents.each(function(div, i) {
if (i != 0) {
div.setStyle(‘display’, ‘none’);
}
})

menus.each(function(quick_link, i) {
quick_link.getElement(“a”).blur();
quick_link.addEvent(‘click’, function(event) {
e = new Event(event).stop();
contents[selected_menu].setStyle(‘display’, ‘none’);
menus[selected_menu].removeClass(‘selected’);

contents[i].setStyle(‘display’, ‘block’);
quick_link.addClass(‘selected’);
selected_menu = i;
});
});

#Menu_01을 제외한 다른 content들은 가려주었고, tab menu의 박스에 click 이벤트를 걸어줌으로써 toggle 기능이 완성이 되었다.
만약 content들을 CSS에서 가려주었다면(#Menu_02, #Menu_03 display:none) CSS는 render가 되었는데 Javascript가 동작이 안되는 상황이 오면 다른 content에 접근할 방법이 없어진다.
Javascript로 원하는 content를 display:block으로 바꿔줘야 하는데 Javascript가 동작이 안되니 tab을 백날눌러도 그 tab의 content는 볼 수 가 없게 되는 것이다.

결론.
결국은 content는 CSS와 Javascipt에 영향을 받지 않게 설계,코딩 되어야 하고 더불어 semantic하게 markup되어야 한다는 것이다.

다운로드
미리보기 (링크걸리는줄 알았는데 그게 아니네요. 아..이럴때 개인서버가 살아있었다면..)

 tab-menu.html

압축파일(html, js, images)

 tab-menu.zip

ps > 이거 스크롤의 압박이;;

 

JSSpec용 EditPlus ACP,STX 파일

간략하게 JSSpec을 설명하자면 Javascript BDD 툴입니다.
JSSpec과 BDD에 대한 설명은 다음에 기회될때 포스팅하기로 하고..(과연..?)
일단, 자세한 설명은 JSSpec홈페이지 http://code.google.com/p/jsspec/를 참고하세요~

Editplus용 자동완성파일 ACP, 구문파일 STX을 만들었습니다.

jscript.zip (2007-05-10)
JScript stx with Prototype.js – W. Jordan
jscript.acp.zip (2007-05-10)
JScript acp, ctl with Prototype.js – W. Jordan

이것들이 원본인데 제 입맛에 맞춰서 수정을 해서 쓰다가 JSSpec구문을 추가한 것입니다.
원본이 With Prototype이어서 prototype을 쓰시는 분들께는 사용하시기 더 편리하지 않을까 생각합니다.

만약 사용하시던 ACP, STX가 있으시면 제가 추가한 부분(JSSpec으로 검색해서 나오는 부분)만 현재 사용하시는 파일에 추가를 해주시면 됩니다.

다운로드 >>http://editplus.com/kr/html.html 에서 다운받으실 수 있습니다. (js7.zip)

acp에 추가된 내용

#T=_________________
#T=  JSSpec
#T=jss
describe(“^!”, {
“should “: function() {

}
});
#T=vof
value_of(“^!”)
#T=ept
expect(^!)
#T=sb
should_be(^!)
#t=snb
should_not_be(^!)
#t=sbe
should_be_empty(^!)
#t=snbe
should_not_be_empty(^!)
#t=sbt
should_be_true(^!)
#t=sbf
should_be_false(^!)
#t=snbt
should_not_be_true(^!)
#t=snbf
should_not_be_false(^!)
#t=sh
should_have(^!)
#t=she
should_have_exactly(^!)
#t=shal
should_have_at_least(^!)
#t=sham
should_have_at_most(^!)
#t=si
should_include(^!)
#t=sni
should_not_include(^!)
#t=sm
should_match(^!)
#t=snm
should_not_match(^!)
#t=sf
should_fail(^!)

stx에 추가된 내용

#KEYWORD=JSSPec
describe
value_of
expect
beforebe_each
should_be
should_not_be
should_be_empty
should_not_be_empty
should_be_true
should_be_false
should_not_be_true
should_not_be_false
should_have
should_have_exactly
should_have_at_least
should_have_at_most
should_include
should_not_include
should_match
should_not_match
should_fail

 

정규식을 이용하여 ltrim, rtrim, trim 구현하기

엄청 간단합니다.

String.prototype.trim = function(){
return this.replace(/^(\s|&nbsp;)+|(\s|&nbsp;)+$/g, “”);
}

String.prototype.ltrim = function(){
return this.replace(/^(\s|&nbsp;)+/g, “”);
}

String.prototype.rtrim = function(){
return this.replace(/(\s|&nbsp;)+$/g, “”);
}

 

str = ”  &nbsp;1234567890   “;
ltrim = str.ltrim();
rtrim = str.rtrim();
trim = str.trim();

result = “<pre>orignal = \”” + str + “\”\n”;
result += “ltrim length = ” + ltrim.length + “, string = \”” + ltrim + “\n”;
result += “rtrim length = ” + rtrim.length + “, string = \”” + rtrim + “\n”;
result += “trim length = ” + trim.length + “, string = \”” + trim + “\n”;

document.write(result);