아홉째 날: Bootstrap + Bootswatch + Mojolicious::Plugin::Bootstrap3 삼종셋트

저자

@keedi - Seoul.pm 리더, Perl덕후, 거침없이 배우는 펄의 공동 역자, keedi.k at gmail.com

시작하며

일곱 번째 기사와 더불어 이번에도 삼종셋트 시리즈입니다. :-) 웹 화면에서 미려하면서도 통일된 디자인은 무척 중요합니다. 이전 기사와 마찬가지로 오픈 소스로 공개된 많은 디자인 관련 라이브러리 중 펄(Perl)과 Mojolicious와 함께 간단히 사용하는 것 만으로 웹 화면의 품질을 월등히 높일 수 있답니다. Bootstrap은 현재 가장 유명한 반응형 HTML, CSS, JS 오픈소스 프레임워크이며, Bootswatch는 Bootsrap을 위한 무료 오픈소스 테마입니다. 더불어 CPAN의 Mojolicious::Plugin::Bootstrap3 모듈은 Mojolicious에서 Bootstrap과 Bootswatch를 손쉽게 사용할 수 있게 도와주는 플러그인입니다. 역시 이번에도 얼마나 간단히 이 삼종셋트를 이용할 수 있는지 궁금하지 않나요?

준비물

필요한 모듈은 다음과 같습니다.

직접 CPAN을 이용해서 설치한다면 다음 명령을 이용해서 모듈을 설치합니다.

$ sudo cpan \
    Mojolicious \
    Mojolicious::Plugin::Bootstrap3

사용자 계정으로 모듈을 설치하는 방법을 정확하게 알고 있거나 perlbrew를 이용해서 자신만의 Perl을 사용하고 있다면 다음 명령을 이용해서 모듈을 설치합니다.

$ cpan \
    Mojolicious \
    Mojolicious::Plugin::Bootstrap3

Mojolicious

Mojolicious는 인기있는 펄의 경량 웹 프레임워크입니다. 간단히 Mojolicious를 이용해서 당장 돌릴 수 있는 최소한의 페이지를 꾸며보죠. 웹에서 해당 주소의 가장 첫 페이지를 의미하는 랜딩 페이지(landing page) 정도면 적당하겠죠? Bootstrap 예제 중 점보트론 페이지를 이용해서 테스트하면 적당할 것 같네요.

명령줄에서 다음 명령을 실행합니다.

$ mkdir jumbotron
$ cd jumbotron
$ mojo generate lite_app jumbotron.pl
[exist] /home/askdna/jumbotron
[write] /home/askdna/jumbotron/jumbotron.pl
[chmod] /home/askdna/jumbotron/jumbotron.pl 744
$ 

생성된 jumbotron.pl 파일의 내용은 다음과 같습니다.

#!/usr/bin/env perl
use Mojolicious::Lite;

# Documentation browser under "/perldoc"
plugin 'PODRenderer';

get '/' => sub {
my $c = shift;
$c->render(template => 'index');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>

기존 파일의 내용에 연연하지 말고 jumbotron.pl 파일을 다음처럼 바꿔 볼까요?

#!/usr/bin/env perl

use Mojolicious::Lite;

get "/" => "index";

app->start;

__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Jumbotron Template for Seoul.pm Advent Calendar</title>
  </head>

  <body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <form class="navbar-form navbar-right">
            <div class="form-group">
              <input type="text" placeholder="Email" class="form-control">
            </div>
            <div class="form-group">
              <input type="password" placeholder="Password" class="form-control">
            </div>
            <button type="submit" class="btn btn-success">Sign in</button>
          </form>
        </div><!--/.navbar-collapse -->
      </div>
    </nav>

    <!-- Main jumbotron for a primary marketing message or call to action -->
    <div class="jumbotron">
      <div class="container">
        <h1>Hello, world!</h1>
        <p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more &raquo;</a></p>
      </div>
    </div>

    <div class="container">
      <!-- Example row of columns -->
      <div class="row">
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
      </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
      </div>

      <hr>

      <footer>
        <p>&copy; 2015 Company, Inc.</p>
      </footer>
    </div> <!-- /container -->

  </body>
</html>

자, 이제 화면에 작성한 점보트론 화면이 잘 나타나는지 확인해보죠. 명령줄에서 다음 명령을 실행해서 웹 응용을 구동시킵니다.

$ morbo jumbotron.pl
Server available at http://127.0.0.1:3000
[Fri Dec  4 08:51:39 2015] [debug] Your secret passphrase needs to be changed

브라우저에서 http://localhost:3000 주소로 접속해서 화면을 살펴보세요.

jumbotron without bootstrap 그림 1. 첫 번째 버전 - without Bootstrap (원본)

일단 점보트론 페이지가 보이는 것을 확인했습니다. Bootstrap 자원을 전혀 적재하지 않았기 때문에 무척 수수하게 보입니다.

Bootstrap + Mojolicious::Plugin::Bootstrap3

Mojolicious::Plugin::Bootstrap3 모듈을 사용하려면 Mojolicious 웹 응용 코드에 해당 플러그인을 적재하는 코드를 추가해야 합니다.

...
use Mojolicious::Lite;

plugin "bootstrap3";
...

플러그인을 적재한 뒤에는 템플릿 영역에서 asset 키워드를 이용해 Bootstrap 관련 정적 파일을 HTML에 적재할 수 있습니다. __DATA__ 섹션 하부의 index.html.ep 템플릿 영역 중 head 태그 영역을 다음 내용으로 대체합니다.

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
  <meta name="description" content="">
  <meta name="author" content="">

  <!-- Bootstrap -->
  %= asset "bootstrap.css"
  %= asset "bootstrap.js"

  <title>Jumbotron Template for Seoul.pm Advent Calendar</title>
</head>

브라우저로 접속해서 화면을 살펴보세요.

jumbotron with bootstrap 그림 2. 두 번째 버전 - with Bootstrap (원본)

"Hello, world!" 배너가 조금 위로 치우친 것만 빼면 제법 비슷하군요. CSS를 약간만 수정해보죠.

__DATA__ 섹션 하부의 index.html.ep 템플릿 영역 중 head 태그 영역에 CSS를 추가합니다.

...
<!-- Bootstrap -->
%= asset "bootstrap.css"
%= asset "bootstrap.js"

<title>Jumbotron Template for Seoul.pm Advent Calendar</title>

<style>
  /* Move down content because we have a fixed navbar that is 50px tall */
  body {
    padding-top: 50px;
    padding-bottom: 20px;
  }
</style>
...

이제 Bootstrap 홈페이지의 점보트론 예제와 거의 비슷하죠? :-)

jumbotron with bootstrap + css 그림 3. 세 번째 버전 - with Bootstrap + CSS (원본)

Bootswatch + Mojolicious::Plugin::Bootstrap3

Mojolicious::Plugin::Bootstrap3 모듈은 이미 모듈 자체적으로 Bootswatch 테마를 지원하기 때문에 플러그인 적재 시점에 간단히 사용할 Bootswatch를 지정하고 해당 CSS를 사용하도록만 수정하면 Bootswatch가 자동으로 적용됩니다.

Mojolicious::Plugin::Bootstrap3 모듈 적재 영역의 코드를 다음처럼 수정합니다.

#!/usr/bin/env perl

use Mojolicious::Lite;

plugin "bootstrap3" => {
    theme => {
        paper => "https://bootswatch.com/paper/_bootswatch.scss",
    },
};
...

theme 키 하부의 paper 키는 플러그인이 인지할 수 있도록 사용자가 지정하는 값으로 paper.css로 접근합니다. 뒤의 링크 주소는 Bootswatch 공식 홈페이지에서 제공하는 paper 테마SCSS 파일 주소입니다.

__DATA__ 섹션 하부의 index.html.ep 템플릿 영역 중 head 태그 영역 에서 asset으로 부트스트랩을 적재하던 부분을 다음처럼 수정합니다.

<!-- Bootstrap + Bootswatch -->
%= asset "paper.css"
%= asset "bootstrap.js"

jumbotron with bootstrap + css 그림 4. 네 번째 버전 - with Bootswatch 'paper' 테마 (원본)

짜잔~! 간단하죠? ;-)

전체 코드

전체 코드는 다음과 같습니다.

#!/usr/bin/env perl

use Mojolicious::Lite;

plugin "bootstrap3" => {
    theme => {
        paper => "https://bootswatch.com/paper/_bootswatch.scss",
    },
};

get "/" => "index";

app->start;

__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Bootstrap + Bootswatch -->
    %= asset "paper.css"
    %= asset "bootstrap.js"

    <title>Jumbotron Template for Seoul.pm Advent Calendar</title>

    <style>
      /* Move down content because we have a fixed navbar that is 50px tall */
      body {
        padding-top: 50px;
        padding-bottom: 20px;
      }
    </style>
  </head>

  <body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <form class="navbar-form navbar-right">
            <div class="form-group">
              <input type="text" placeholder="Email" class="form-control">
            </div>
            <div class="form-group">
              <input type="password" placeholder="Password" class="form-control">
            </div>
            <button type="submit" class="btn btn-success">Sign in</button>
          </form>
        </div><!--/.navbar-collapse -->
      </div>
    </nav>

    <!-- Main jumbotron for a primary marketing message or call to action -->
    <div class="jumbotron">
      <div class="container">
        <h1>Hello, world!</h1>
        <p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more &raquo;</a></p>
      </div>
    </div>

    <div class="container">
      <!-- Example row of columns -->
      <div class="row">
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
      </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
      </div>

      <hr>

      <footer>
        <p>&copy; 2015 Company, Inc.</p>
      </footer>
    </div> <!-- /container -->

  </body>
</html>

정리하며

Bootstrap + Bootswatch + Mojolicious::Plugin::Bootstrap3 삼종셋트는 어떠셨나요? 이전 삼종셋트 만큼이나 간단하죠? 오픈소스 프레임워크와 오픈소스 테마를 이용해서 웹을 만든다는 것은 정말 즐거운 일입니다. 여기에 펄과 Mojolicious, Mojolicious::Plugin::Bootstrap3 모듈까지 함께라면 신바람나게 개발할 수 있답니다. 이제 멋진 웹을 만들 일만 남았군요!

Enjoy Your Perl! ;-)

EOT

blog comments powered by Disqus