https://www.digitalocean.com/pricing
Price 5$
RAM 512 MB
SSD 20GB
Transfer 1TB
Core 1
이정도면 연습용으로 쓸만한듯..
근데 리젼이 어디잇는거징;;
국내인가? ㅋㅋ 해외아니양;; ㅠ 영어로되어있는거보니...왠지 불안 ㅋㅋㅋ
AWS.. 은근히 돈 받아머거! ㅋㅋ
https://www.digitalocean.com/pricing
Price 5$
RAM 512 MB
SSD 20GB
Transfer 1TB
Core 1
이정도면 연습용으로 쓸만한듯..
근데 리젼이 어디잇는거징;;
국내인가? ㅋㅋ 해외아니양;; ㅠ 영어로되어있는거보니...왠지 불안 ㅋㅋㅋ
AWS.. 은근히 돈 받아머거! ㅋㅋ
'제대로 배우는 NodeJS p170. ' 에 관한 내용이다.
처음에 MVC라고 해서 무슨 말인가 했다.
express말고 다른 MVC 모델 프레임웍을 소개하는건가 했다.
확장하기 편하도록 한 것으로 보인다.
이걸 MVC라 하기에는.. 좀 억지가 있어 보였다. '뭐..보는 사람마다 이해하는 사람마다 다르겠지만..'
내가 볼때에는 그냥 Visitor 패턴을 활용한 확장성을 높여준 코드로 보였다.
좀 더 풀어 쓰면,
Visitor 패턴을 활용한 CRUD 코드 작성하는 예제 코드라 생각하면 좋겠다.
나는 CRUD는 IO접근을 위한 CRUD로 생각하고 있었지.. 이걸 따로 MVC로 CRUD를 구현했다는건지 어떤 의도였는지는 잘모르겠다. 뭐 여튼 결론적으로 하는 말은 같은것 같다. 편하게 코드짜게 해준다? ^^;
// CRUD 연결 메소드
exports.mapRoute = function ( app. prefix ) {
prefix = '/' + prefix;
var prefixObj = require( './controller/' + prefix );
// CRUD 연결 해주는 부분 : 색인 / 추가 / 조회 / 편집 / 업데이트 / 제거
app.get( prefix, prefixObj.index );
app.get( prefix + '/new', prefixObj.new );
app.get( prefix + '/:id', prefixObj.show);
app.post( prefix + '/create'. prefixObj.create)
app.get( prefix + '/:id/edit', prefixObj.edit);
app.put( prefix + '/:id', prefix.update);
app.del( prex + '/:id', prefixObj.destroy);
};
// 서버구동 부분에서 등록
...
app.get('/', route.index);
var prefixes = ['widgets'];
prefixes.forEach( function( prefix) {
map.mapRoute( app, prefix );
});
....
// Widgets.js의 CRUD하는 실체 부분
exports.new = function( req, res ) { ... }
exports.create = function( req, res ) { ... }
exports.show = function( req, res ) { ... }
exports.destroy = function( req, res ) { ... }
exports.edit = function( req, res ) { ... }
exports.update = function( req, res ) { ... }
이렇게 하면~ 기본 단계 완성이 된다~
여기서 어떻게 확장이 되냐고?
위에 굵게 해둔 부분에서 추가 확장할 route를 만들면된다.
var prefixes = ['widgets', 'pictures', 'musics' ];
이렇게 한 후, pictures.js와 musics.js파일을 만들어서 똑같은 template으로 CRUD를 제공해 주면 됨! ㅋㅋ
요약 해서 말하면,
Controller |
CRUD 연결 컨트롤러 생성 |
mapRoute(); |
Model |
CRUD 실체 ( ex; Widgets ) 구현 |
widgets.exports.CRUD(); |
View |
App Route에 연결 |
prefixes.forEach(); |
cURL로 테스트가 된다~ ㅋㅋ
curl --request GET http://ip:3000/widgets/new
curl --request POST http://ip:3000/widgets/create --data 'widgetname=name&widgetprice=1.0'
요러케~
난 갠적으로 다른 테스트툴을 쓰는데~ 간편하게 curl로 확인하는 것도 괜찮은 듯 하다~
MVC 흉내 내기 끝.
[NodeJS] static simple http 서버 (0) | 2013.10.30 |
---|---|
[NODEJS] chatting server git source (0) | 2013.10.23 |
[NodeJS] http proxy 랑 router 살짝 섞으니 좋군 (0) | 2013.08.27 |
[NodeJS] 패키지로 설치하기 (0) | 2013.08.25 |
[NodeJS] node.js 앱의 인스턴스를 관리해 주는 forever (0) | 2013.08.21 |
현재 보는 책은 '제대로 배우는 NodeJS'
메모하고자 하는 것은 색인을 위한 문장
페이지 150p.
./node-http-proxy --port 8000 --tartget localhost:8124
페이지 151p.
코드를 이용해서 port proxy 사용
uri값에 따라 port분기함
if req.url.match( /^\/node\// ) proxy.proxyRequest( req, res, { host : 'localhost', port : 8000 });
else proxy.proxyRequest( req, res, { host : 'localhost', port : 8124 });
이게 된다는 거임..
그래서 URL을 아래같이 요청하면 프록시에서 분기시킴
/node/123 -> localhost:8000
/example.html -> localhost:8124
/node/567 -> localhost:8000
/htmltest/wow123 -> localhost:8124
^^; 색인용으로 간단히 메모만 함.
[NODEJS] chatting server git source (0) | 2013.10.23 |
---|---|
[NodeJS] Express를 MVC로 활용 (0) | 2013.08.27 |
[NodeJS] 패키지로 설치하기 (0) | 2013.08.25 |
[NodeJS] node.js 앱의 인스턴스를 관리해 주는 forever (0) | 2013.08.21 |
[NodeJS] Webserver 셋팅 (0) | 2013.08.21 |
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install nodejs-dev
[NODEJS] chatting server git source (0) | 2013.10.23 |
---|---|
[NodeJS] Express를 MVC로 활용 (0) | 2013.08.27 |
[NodeJS] http proxy 랑 router 살짝 섞으니 좋군 (0) | 2013.08.27 |
[NodeJS] node.js 앱의 인스턴스를 관리해 주는 forever (0) | 2013.08.21 |
[NodeJS] Webserver 셋팅 (0) | 2013.08.21 |
제이드는 Haml로부터 큰 영향을 받은 고성능 템플릿 엔진이며 node를 위해 자바스크립트로 구현되었다.
each
를 이용하여 투명하게 이터레이션 지원
npm을 이용한다.
npm install jade
var jade = require('jade');
// Compile a function
var fn = jade.compile('string of jade', options);
fn(locals);
self
로컬 값을 포함하기 위해 self
네임스페이스를 사용한다. 기본값은 falselocals
로컬 변수 객체filename
Used in exceptions, and required when using includes debug
Outputs tokens and function body generatedcompiler
Compiler to replace jade's defaultcompileDebug
When false
no debug instrumentation is compiledCRLF 와 CR 은 파싱되기 전에 LF로 변환된다.
태그는 앞에 나오는 간단한 단어다.
html
예를 들면 위 태그는 <html></html>
로 변환된다.
태그는 id값을 가질 수 있다.
div#container
위 코드는 다음과 같이 변환된다. <div id="container"></div>
클래스는 어떻게 할까?
div.user-details
다음처럼 렌더링 된다. <div class="user-details"></div>
클래스가 복수개 일때는?그리고 id도 붙어 있으면? 물론 가능하다.
div#foo.bar.baz
는 다음과 같다. <div id="foo" class="bar baz"></div>
div div div 은 확실히 짜증난다. 다음처럼 해보자
#foo
.bar
위 코드는 이미 오랜기간 우리가 작성해왔던 코드에 대한 꼼수다. 결과는 다음과 같다.
`<div id="foo"></div><div class="bar"></div>`
태그 뒤에 내용을 표시한다.
p wahoo!
렌더링하면 <p>wahoo!</p>
가 된다.
꽤 쓸만하다. 그럼 긴 텍스트 문장일 경우엔 어떻게 할까?
p
| foo bar baz
| rawr rawr
| super cool
| go jade go
위 코드는 다음처럼 렌더링 된다. <p>foo bar baz rawr.....</p>
인터폴레이션(interpolation, 중간중간 끼워넣어 완성시키는 것)은? 당근! 만약 다음과 같은 값 { name: 'tj', email: 'tj@vision-media.ca' }
을 컴파일 함수로 넘긴다면, 아래와 같은 일을 할 수 있다.
#user #{name} <#{email}>
결과는 <div id="user">tj <tj@vision-media.ca></div>
"#{animals} on a #{transport}".interpolate({ animals: "Pigs", transport: "Surfboard" });
출력은
"Pigs on a Surfboard"
특정 이유로 #{}
를 출력하고 싶다면? 이스케이프 처리해라!
p \#{something}
위와 같이하면 다음 처럼 된다. <p>#{something}</p>
이스케이프 처리하지 않길 바랄때 다음과 같이 #대신 !를 쓴다. !{html}
,
- var html = "<script></script>"
| !{html}
위 html 변수안의 코드는 이스케이프 처리되지 않는다.
중첩된 태그들 또한 선택적으로 텍스트 블럭을 사용할 수 있다.
label
| Username:
input(name='user[name]')
혹은 바로 태그 텍스트를 불일 수 있다.
label Username:
input(name='user[name]')
오직 텍스트만 쓸 수 있는 script
, style
, 그리고 textarea
같은 태그들은 긴 문장이라도 앞에 |
문자를 붙일 필요가 없다.
html
head
title Example
script
if (foo) {
bar();
} else {
baz();
}
반대로, 텍스트 블럭의 을 나타내기 위해 마지막에 '.'을 붙일 수도 있다.
p.
foo asdf
asdf
asdfasdfaf
asdf
asd
출력:
<p>foo asdf
asdf
asdfasdfaf
asdf
asd
</p>
끝에 '.'을 붙일 때 공백을 주면 Jade파서는 무시한다. 일반 문자로 간주하게 된다.
p .
출력:
<p>.</p>
만약 이스케이프 문자(\)를 찍고 싶으면 두개를 붙인다. 즉, 다음처럼 출력하고 싶다면
</p>foo\bar</p>
아래 처럼 쓴다.
p.
foo\\bar
한 줄 주석은 자바스크립트 코멘트랑 같다. '//'를 붙이고 한 줄로 쓴다.
// just some paragraphs
p foo
p bar
출력은 다음처럼 된다.
<!-- just some paragraphs -->
<p>foo</p>
<p>bar</p>
하이픈을 붙이면 파싱할 때 제외한다.
//- will not output within markup
p foo
p bar
출력
<p>foo</p>
<p>bar</p>
블럭 주석은 일반적으로 다음과 같다.
body
//
#content
h1 Example
출력은
<body>
<!--
<div id="content">
<h1>Example</h1>
</div>
-->
</body>
Jade는 조건절 주석도 잘 지원한다.
head
//if lt IE 8
script(src='/ie-sucks.js')
출력:
<body>
<!--[if lt IE 8]>
<script src="/ie-sucks.js"></script>
<![endif]-->
</body>
Jade는 일반적인 방식으로 태그 정의에 중첩을 지원한다.
ul
li.first
a(href='#') foo
li
a(href='#') bar
li.last
a(href='#') baz
<ul>
<li id="first"><a href="#">foo</a>
</li>
<li><a href="#">bar</a>
</li>
<li class="last"><a href="#">baz</a>
</li>
</ul>
블럭 확장은 한줄짜리 중첩 태그를 만들 수 있게 해준다. 다음 예제는 위 예제와 동일하다.
ul
li.first: a(href='#') foo
li: a(href='#') bar
li.last: a(href='#') baz
Jade는 현재 속성 구분자로 '(' 와 ')'를 사용한다.
a(href='/login', title='View login page') Login
속성의 값이 undefined
나 null
이면 표시되지 않는다.
div(something=null)
boolean 속성도 지원한다.
input(type="checkbox", checked)
코드가 붙은 boolean 속성은 코드의 값이 true
일 때만 속성이 표시된다.
input(type="checkbox", checked=someValue)
여러 라인에 걸쳐서도 잘 동작한다.
input(type='checkbox',
name='agreement',
checked)
콤마가 없는 여러 라인일 경우도 잘 된다.
input(type='checkbox'
name='agreement'
checked)
펑키한 공백? 된다:
input(
type='checkbox'
name='agreement'
checked)
콜론도 된다.
rss(xmlns:atom="atom")
{ id: 12, name: 'tobi' }
값을 나타내는 user라는 로컬 변수가 있다고 가정해보자. 앵커 태그가 "/user/12"를 가르키길 원한다면, 자바스크립트의 문자열 연결방식을 사용할 수 있다.
a(href='/user/' + user.id)= user.name
혹은 jade은 인터폴레이션을 쓸 수도 있다. 왜냐하면 루비를 쓰거나 커피스크립트를 쓰는 사람들이 일반적으로 쓰는 것 같아서 나도 추가했다.
a(href='/user/#{user.id}')= user.name
class
속성은 배열을 받는 특별 케이스다. bodyClasses = ['user', 'authenticated']
를 다음처럼 넘길 수 있다.
body(class=bodyClasses)
인라인 HTML도 잘 동작한다. 파이프 문법을 이용해서 수직으로 글자를 내려 쓸 수 있다.
html
body
| <h1>Title</h1>
| <p>foo bar baz</p>
파이프를 생략하기 위해 끝에 .을 붙여서 Jade에게 텍스트 블럭임을 알려줄 수 있다.
html
body.
<h1>Title</h1>
<p>foo bar baz</p>
위 코드는 아래와 같다
<html><body><h1>Title</h1>
<p>foo bar baz</p>
</body></html>
위와 같은 규칙은 어턴 텍스트가 있던 jade에서는 동일한 규칙으로 동작한다.
html
body
h1 User <em>#{name}</em>
독타입을 추가하려면 !!!
, 혹은 선택적으로 doctype
을 붙인다.
!!!
위 내용은 transitional doctype이 된다.
!!! 5
혹은
!!! html
혹은
doctype html
독타입은 대소문자를 가리지 않는다. 따라서 다음 내용은 동일하다.
doctype Basic
doctype basic
독타입 문자열을 전달 할 수도 있다.
doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN
결과:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN>
바꾸고 싶으면 아래처럼 간단히 된다.
jade.doctypes.default = 'whatever you want';
필터들은 앞에 :
를 붙인다. 이를테면 :markdown
다음 이어지는 텍스트 블럭은 필터 함수를 탄다. 맨 위 기능항목에서 사용 가능한 필터들을 볼 수 있다.
body
:markdown
Woah! jade _and_ markdown, very **cool**
we can even link to [stuff](http://google.com)
렌더링되면:
<body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://google.com">stuff</a></p></body>
Jade에서는 세 가지 종류의 실행 코드를 지원한다.첫 째는 -
를 앞에 붙이는 것이다. 출력물로 변환되지 않는다.
- var foo = 'bar';
조건문이나 반복문에도 쓸 수 있다.
- for (var key in obj)
p= obj[key]
Jade의 버퍼링 기술덕분에 다음과 같은 것도 잘 된다.
- if (foo)
ul
li yay
li foo
li worked
- else
p oh no! didnt work
헐~ 심지어 복잡한 이터레이션도 된다.:
- if (items.length)
ul
- items.forEach(function(item){
li= item
- })
원한다면 뭐든!
두 번째는 이스케이프된 버퍼 코드를 가질 수 있다. 앞에 반환값으로 쓰이는 버퍼값에 사용되며 앞에 =
를 붙인다.
- var foo = 'bar'
= foo
h1= foo
결과는 bar<h1>bar</h1>
. 보안상의 이유로 =
가 붙은 버퍼 코드는 기본적으로 이스케이프 처리된다. 이스케이프 처리하고 싶지 않으면 !=
를 쓴다.
p!= aVarContainingMoreHTML
Jade는 또한 디자이너 친화적인 변형을 가지고 있다. 자바스크립트 리터럴을 좀 더 표현적이고 선언적으로 만들어 준다. 예를 들면 다음 할당문은 동등하다.. 그리고 표현은 여전히 일반적인 자바스크립트다.
- var foo = 'foo ' + 'bar'
foo = 'foo ' + 'bar'
비슷하게 Jade는 퍼스트 클래스(first-class) if
, else if
, else
, until
, while
, unless
명령어를 가지고 있다. 하지만, 표현은 여전히 자바스크립트 표현식을 따른다는 걸 기억해야 한다.
if foo == 'bar'
ul
li yay
li foo
li worked
else
p oh no! didnt work
평범한 자바스크립트와 친한 Jade이지만 좀 더 디자이너 친화적인 템플릿을 만드는 것 가능하게 해주는 생성자도 지원한다. 그런 것 중 하나가 each
이다.
each VAL[, KEY] in OBJ
다음은 배열 예다.
- var items = ["one", "two", "three"]
each item in items
li= item
출력은
<li>one</li>
<li>two</li>
<li>three</li>
인덱스로 반복처리를 하려면
items = ["one", "two", "three"]
each item, i in items
li #{item}: #{i}
출력은
<li>one: 0</li>
<li>two: 1</li>
<li>three: 2</li>
객체의 키와 값으로 반복처리를 하려면:
obj = { foo: 'bar' }
each val, key in obj
li #{key}: #{val}
위 코드의 출력은 <li>foo: bar</li>
내부적으로 Jade는 이런 문장들을 users.forEach(function(user){
와 같은 일반적인 자바스크립트 반복문으로 변환하다. 따라서 렉시컬 스코프와 중첩적용은 일반적인 자바스크립트 규칙을 따른다.
each user in users
each role in user.roles
li= role
원하면 for
도 쓸 수 있다.
for user in users
for role in user.roles
li= role
Jade의 조건절은 (-
) 접두어 붙은 코드를 사용하는 방법과 같다. 하지만 좀 더 디자이너 친화적인 방식을 제공하는데, 이 역시도 일반적인 자바스크립트 표현식이라는 걸 잊지말길 바란다.
for user in users
if user.role == 'admin'
p #{user.name} is an admin
else
p= user.name
위 코드는 다음과 같은 자바스크립트 리터럴를 사용하는 것과 같다
for user in users
- if (user.role == 'admin')
p #{user.name} is an admin
- else
p= user.name
Jade는 unless
라는 키워드를 가지고 있는데, 이는 자바스크립트의 if (!(expr))
에 해당한다.
for user in users
unless user.isAnonymous
p
| Click to view
a(href='/users/' + user.id)= user.name
Jade는 block
와 extends
키워드를 이요해서 템플릿 상속을 지원한다. 블럭은 말그대로 Jade의 'block'이다. 자식 템플릿으로 교체되며, 재귀적으로 적용된다.
원한다면 Jade의 블럭은 기본 내용을 갖고 있을 수 도 있다. 하지만 선택사항이고, block scripts
, block content
, 그리고 block foot
옵션으로 사용할 수 있다.
html
head
h1 My Site - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p some footer content
그리고 레이아웃을 확장하고 싶다면 새로운 파일을 만들어서 extends
지시어를 아래 코드처럼 사용한다. 지시어 옆에는 경로를 쓸 수 있으며 .jade 확장자를 붙이는 건 선택사항이다. 하나 혹은 그 이상의 블럭도 정의할 수 있는 데 해당 블럭은 부모 블럭 컨텐트를 덮어쓰게된다. 아래 코드에서 foot 블럭은 정의되지 않았기 때문에 결과는 "some footer content"라고 출력될 것이다.
extends extend-layout
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
each pet in pets
include pet
또한 추가적인 블럭들을 제공하기 위해 어떤 블럭을 덮어쓰는 것도 가능하다. 다음 예제를 보면 content
가 sidebar
와primary
를 덮어쓰기용 블럭으로 표현해 놓았다. 자식 템플릿은 필요에 따라서는 content
를 통으로 덮어쓸수도 있다.
extends regular-layout
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing
인클루드는 정적으로 Jade 덩어리들, 혹은 css, html 같이 별도로 분리되어 있는 파일들을 포함할 수 있다. 고전적인 예제는 헤더와 풋터를 인클루딩 하는 것이다. 다음과 같은 폴더 구조를 가지고 있다고 가정해 보자.
./layout.jade
./includes/
./head.jade
./tail.jade
그리고 다음은 layout.jade 파일이다.
html
include includes/head
body
h1 My Site
p Welcome to my super amazing site.
include includes/foot
includes/head and includes/foot 둘다 layout.jade의 filename
옵션에 맞춰 상대 경로로 포함한다. 물론 절대 경로도 쓸 수 있다. 하지만 Express가 해당 일을 처리한다. 포함한 다음, 해당 파일들을 파싱해서 기대한 대로 AST에 끼워넣는다. (옮긴이주. AST: Abstract syntax tree)
<html> <head> <title>My Site</title> <script src="/javascripts/jquery.js"> </script><script src="/javascripts/app.js"></script> </head> <body> <h1>My Site</h1> <p>Welcome to my super lame site.</p> <div id="footer"> <p>Copyright>(c) foobar</p> </div> </body> </html>
이미 언급했듯이 include
는 html이나 css같은 다른 콘텐츠도 포함시킬 수 있다. 확장자를 보고 Jade가 해당 파일이 Jade 소스가 아니라고 판단하면 문자 그대로 포함만 한다.
html
body
include content.html
인클루드 지시자는 블럭에 쓸 수 도 있다. 해당 경우 주어진 블럭은 파일에서 정의된 블럭의 마지막에 추가된다. 이를테면 head.jade
가 아래 내용을 포함하고 있을 때
head
script(src='/jquery.js')
아래 처럼 블럭에 include head
을 써서 두 개의 스크립트를 추가할 수도 있다. (이건 직접 한번 해보세요! :)
html
include head
script(src='/foo.js')
script(src='/bar.js')
body
h1 test
믹스인은 컴파일된 템플릿 내에서 일반적인 자바스크립트로 변환된다. 믹스인은 필요에 따라서는 인자도 가질 수도 있다.
mixin list
ul
li foo
li bar
li baz
믹스인을 인자없이 쓰면 블럭이랑 비슷하게 보인다.
h2 Groceries
mixin list
믹스인은 하나 이상의 인자를 가질 수 있다. 인자는 일반적인 자바스크립트 표현식처럼 쓴다. 다음 예제를 보자.
mixin pets(pets)
ul.pets
- each pet in pets
li= pet
mixin profile(user)
.user
h2= user.name
mixin pets(user.pets)
Would yield something similar to the following html:
<div class="user">
<h2>tj</h2>
<ul class="pets">
<li>tobi</li>
<li>loki</li>
<li>jane</li>
<li>manny</li>
</ul>
</div>
mixin field(type, name, label)
.field(class='field-' + type)
label #{label}:
input(type=type, name='user[#{name}]', value=user[name])
//실제 템플릿 코드
form
mixin field('text', 'name', 'Username')
mixin field('text', 'email', 'Email')
mixin field('password', 'pass', 'Password')
input(type='submit', value='Sign Up')
<form>
<div class="field field-text">
<label>Username:</label>
<input type="text" name="user[name]" value="TJ Holowaychuk"/>
</div>
<div class="field field-text">
<label>Email:</label>
<input type="text" name="user[email]" value="tj@learnboost.com"/>
</div>
<div class="field field-password">
<label>Password:</label>
<input type="password" name="user[pass]"/>
</div>
<input type="submit" value="Sign Up"/>
</form>
Usage: jade [options] [dir|file ...]
Options:
-h, --help output usage information
-v, --version output the version number
-o, --obj <str> javascript options object
-O, --out <dir> output the compiled html to <dir>
-p, --path <path> filename used to resolve includes over stdio
Examples:
# translate jade the templates dir
$ jade templates
# create {foo,bar}.html
$ jade {foo,bar}.jade
# jade over stdio
$ jade < my.jade > my.html
# jade over stdio specifying filename to resolve include directives
$ jade < my.jade -p my.jade > my.html
# jade over stdio
$ echo "h1 Jade!" | jade
# foo, bar dirs rendering to /tmp
$ jade foo bar --out /tmp
[Jade] Basic Reference. (0) | 2013.08.23 |
---|
유용한거 몇가지만 스크랩~
( 다 깨지네;; 레이아웃 안맞아서 그런듯~ ^^; )
Unbuffered code starts with -
does not add any output directly, e.g.
- for (var x = 0; x < 3; x++)
li item
<li>item</li>
<li>item</li>
<li>item</li>
Jade's first-class conditional syntax allows for optional parenthesis, and you may now omit the leading -
otherwise it's identical, still just regular javascript:
- var user = { description: 'foo bar baz' }
#user
if user.description
h2 Description
p.description= user.description
else
h1 Description
p.description User has no description
<div id="user">
<h2>Description</h2>
<p class="description">foo bar baz</p>
</div>
Jade also provides a negated version unless
(the following are therefore equivallent):
unless user.isAnonymous
p You're logged in as #{user.name}
if !user.isAnonymous
p You're logged in as #{user.name}
Jade's first-class iteration syntax makes it easier to iterate over arrays and objects within a template:
ul
each val in [1, 2, 3, 4, 5]
li= val
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
You can also get the index as you iterate:
ul
each val, index in ['one', 'two', 'three']
li= index + ': ' + val
<ul>
<li>1: one</li>
<li>2: two</li>
<li>3: three</li>
</ul>
Jade also lets you iterate over the keys in an object:
ul
each val, index in {1: 'one', 2: 'two', 3: 'three'}
li= index + ': ' + val
<ul>
<li>1: one</li>
<li>2: two</li>
<li>3: three</li>
</ul>
The object or array to iterate over is just plain JavaScript so it can be a variable or the result of a function call as well.
The case statement is a shorthand for JavaScript's switch
statement and takes the following form:
- var friends = 10
case friends
when 0
p you have no friends
when 1
p you have a friend
default
p you have #{friends} friends
<p>you have 10 fr
Block expansion may also be used:
- var friends = 1
case friends
when 0: p you have no friends
when 1: p you have a friend
default: p you have #{friends} friends
<p>you have a friend</p>
Filters let you use other languages within a jade template. They take a block of plain text as an input.
:markdown
# Markdown
I often like including markdown documents in my jade templates.
:coffee
console.log 'This is coffee script'
<h1>Markdown</h1>
<p>I often like including markdown documents in my jade templates.</p>
<script>console.log('This is coffee script')</script>
Mixins allow you to create reusable blocks of jade.
//- Declaration
mixin list
ul
li foo
li bar
li baz
//- Use
+list()
+list()
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
They are compiled to functions and can take arguments:
mixin pets(pets)
ul.pets
- each pet in pets
li= pet
+pets(['cat', 'dog', 'pig'])
<ul class="pets">
<li>cat</li>
<li>dog</li>
<li>pig</li>
</ul>
Mixins can also take a block of jade to act as the content:
mixin article(title)
.article
.article-wrapper
h1= title
if block
block
else
p No content provided
+article('Hello world')
+article('Hello world')
p This is my
p Amazing article
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>No content provided</p>
</div>
</div>
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>This is my</p>
<p>Amazing article</p>
</div>
</div>
Mixins currently also get an implicit attributes argument taken from the attributes passed to the mixin:
mixin link(href, name)
a(class=attributes.class, href=href)= name
+link('/foo', 'foo')(class="btn")
<a class="btn" href="/foo">foo</a>
[Jade] Jade - 템플릿 엔진 for Node.js (0) | 2013.08.23 |
---|
forever 설치해서 잘써먹자~
http://blog.outsider.ne.kr/590
node.js에 대한 포스팅을 몰아치고 있군요. 얼마전에 구축했던 Side Effect Studio사이트에서 사용했던 것들을 좀 정리하고 공유하려다 보니까 node.js에 대해서만 좀 연속적으로 올라가고 있네요. 빨리 다 정리하고 다른 것들도 좀 봐야겠습니다. ㅎ
작년에 Upstart와 Monit으로 node.js Application 서비스 하기라는 포스팅을 올린적이 있는데 이는 꽤 유용하긴 하지만 관리차원에서 꽤나 귀찮은 점이 있습니다. upstart스크립트 만들고 monit에 룰 적용하고 하는 등의 일은 약간 귀찮은 일입니다. 딱히 다른 대안을 모르겠어서 Upstart와 Monit을 쓰고 있었는데 저 포스팅 이후 node앱의 인스턴스를 관리해 주는 forever라는 툴이 공개되었습니다.
forever는 npm을 사용해서 npm install forever 명령어로 간단히 설치가 가능하며 아주 간단한 명령어를 통해서 node.js로 만든 앱을 실행시켜주고 예기치 않게 종료되었을때 다시 실행해주거나 stdout을 로그파일로 남겨주는 등의 관리를 해주는 툴입니다. 사용해 보니 약간의 버그가 있기는 한데 기존 Upstart와 Monit조합에 비해서 사용성이 너무 편리해서 node.js앱의 관리는 모두 forever로 갈아탔습니다.
usage: forever [start | stop | stopall | list | cleanlogs] [options] SCRIPT [script options]
options:
start start SCRIPT as a daemon
stop stop the daemon SCRIPT
stopall stop all running forever scripts
list list all running forever scripts
cleanlogs [CAREFUL] Deletes all historical forever log files
forever의 사용법은 위와 같습니다. 등록하고자 하는 스크립트를 forever start app.js와 같이 실행하면 됩니다. 프로세스를 보면 forever에 대한 프로세스가 따로 있어서 실행한 app.js 프로세스가 죽을 경우 자동으로 다시 실행을 시켜주게 됩니다. 현재 돌아가고 있는 스크립트를 보려면 forever list를 실행시키면 됩니다.
프로세스를 종료할때는 앞에 나온 번호를 이용해서 forever stop 번호를 사용하면 됩니다. 한눈에 어떤 프로세스를 현재 사용하고 있는지 파악이 되고 log파일을 자동으로 연결해 주기 때문에 사용하기가 무척 편리합니다.
약간 사용해본 경험으로는 어느정도 안정적인것 같습니다.(별로 접속차가 없어서 fatal이 날 확률이 적기 때문에 정확한건 아니지만 그냥 기분상.. ㅡㅡ;;) 대신 약간의 버그가 있는지 forever start로 앱을 등록했는데 프로세스는 정상적으로 떴는데 forever에는 등록이 되지 않아 리스트에 나타나지 않는 경우가 있습니다. 여러번 테스트를 해보았지만 어떤 규칙성은 못찾았습니다. 이럴때는 해당 스크립트와 그에대한 forever에 대한 프로세스를 강제로 종료하고 다시 등록해주어야 합니다. 이부분 외에는 관리나 사용 모두가 편리해서 참 좋군요.
[NODEJS] chatting server git source (0) | 2013.10.23 |
---|---|
[NodeJS] Express를 MVC로 활용 (0) | 2013.08.27 |
[NodeJS] http proxy 랑 router 살짝 섞으니 좋군 (0) | 2013.08.27 |
[NodeJS] 패키지로 설치하기 (0) | 2013.08.25 |
[NodeJS] Webserver 셋팅 (0) | 2013.08.21 |
겁먹지 말길! 그냥 영어 못해도.. 명령어만 그대로 따라 치면됨~ ㅋㅋ
음... '$' 다음이 명령어임;;
http://www.rs.au.com/31/how-to-install-bootstrap-v2-0-2-in-expressjs-v3-0-0
I’m certainly no expert when it comes with using ExpressJS orBootstrap so there may be far better ways of doing this than what I detail below, however, if you do know of better ways please let me know as I bumbled my way through!
Here goes.
Prerequisites:
I’m installing this on an Ubuntu 11.10 EC2 micro instance and assuming that you have the following installed: node npm make zip unzip git
Process:
~$ npm install -g express less uglify-js
(you may need to sudo npm install -g express less uglify-js
~$ express --css less testme
~$ cd testme
~/testme$ mkdir vendors
~/testme$ cd vendors
~/testme/vendors$ git clone https://github.com/twitter/bootstrap.git bootstrap
~/testme/vendors$ cd bootstrap
~/testme/vendors/bootstrap$ make -i
(you may see a cannot remove `docs/assets/bootstrap.zip`
file –just ignore) – it would also be great if you could make
to a target directory, but I couldn’t find how this could be done.~/testme/vendors$ cd bootstrap/docs/assets
css, img, js
folders and a bootstrap.zip
file: ~/testme/vendors/bootstrap/docs/assets$ ls
testme
folder:~/testme/vendors/bootstrap/docs/assets$ cd ~/testme
~/testme$ mv vendors/bootstrap/docs/assets/bootstrap.zip public
~/testme$ cd public
~/testme/public$ unzip bootstrap.zip
~/testme/public$ ls
rm bootstrap.zip
views/layout.jade
file to include references to the bootstrap files, remember Bootstrap needs the latest jQuery, so you may want to include reference to this too, here’s what my layout.jade
looks like:1234567891011 |
|
views/index.jade
file to include a reference that Bootstrap will be able to use, something like:123456789101112131415161718192021222324252627 |
|
And there you have it! Being able to use a compiled Bootstrap file with your ExpressJS install.
[NODEJS] chatting server git source (0) | 2013.10.23 |
---|---|
[NodeJS] Express를 MVC로 활용 (0) | 2013.08.27 |
[NodeJS] http proxy 랑 router 살짝 섞으니 좋군 (0) | 2013.08.27 |
[NodeJS] 패키지로 설치하기 (0) | 2013.08.25 |
[NodeJS] node.js 앱의 인스턴스를 관리해 주는 forever (0) | 2013.08.21 |