์ง๋ ์ค๊ฑฐ๋ฆฌ
์ด์ ๋ฒ์จ 6์ผ์ด๋ ์ง๋ฌ์ต๋๋ค. ๋ช๋ช ๋ถ๋ค์ ์์ง ์ฐ๋ฆฌ ์ดํ๋ฆฌ์ผ์ด์ ์ด ๊ทธ๋ค์ง ์ ์ฉํ์ง ์๋ค๊ณ ์๊ฐํ์ค์ง๋ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ด๋ค ๋ถ๋ค์ ์ดํ๋ฆฌ์ผ์ด์ ์ด ์ ์ฉํ์ง ๊ทธ๋ ์ง ์์์ง๋ฅผ ์ดํ๋ฆฌ์ผ์ด์ ์ด ์ ๊ณตํ๋ ํ์ด์ง ์๋ก ํ๋จํ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค. ๊ทธ๋ฐ ๋ฉด์์ ๋ณผ๋๋ askeet ์ ๋จ์ํ ์ง๋ฌธ๋ค ๋ชฉ๋ก๊ณผ ์ง๋ฌธ๋ค์ ๋ํ ๋ต๋ณ๋ค์ ์ถ๋ ฅํ๊ณ , ์ฌ์ฉ์ ์ธ์ ์ ๋ค๋ฃจ๋ ์ ๋์ ๋๋ค.
์ฐ๋ฆฌ๊ฐ ํ์ด์ง ์๋ฅผ ์ค์ํ๊ฒ ์๊ฐํ์ง ์๋ ์ด์ ๋ ์ฌํฌ๋์์ ํ์ด์ง ์๋ฅผ ๋๋ฆฌ๋ ๊ฒ์ ์์ฃผ ์ฌ์ด ์ผ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ง์ง์ธ๊ฐ์? ์ข์ต๋๋ค. ์ค๋์ ์ต๊ทผ ์ ๋ ฅ๋ ์ง๋ฌธ๋ค๊ณผ ์ต๊ทผ ๋ต๋ณ๋ ์ง๋ฌธ๋ค์ ์ถ๋ ฅํ๊ณ , ์ฌ์ฉ์ ํ๋กํ ํ์ด์ง, ๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ ํ์ด์ง๋ง๋ค ๋ค๋น๊ฒ์ด์ ๋ฉ๋ด๋ฅผ ๋ฌ์์ ์ ๊ธฐ๋ฅ๋ค์ ์ฌ์ฉํ ์ ์๋๋ก ํด๋ณด๊ฒ ์ต๋๋ค. ์ด ์์ ๋ค์ ํ ์๊ฐ๋ ํ ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์, ๋ทฐ ์ค์ ๊ณผ ์ด๋ฒ ํ ์ฃผ์ ์ด๋ค ์ผ๋ค์ ํด์๋์ง๋ ํจ๊ป ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ค๋น๋์ จ๋์? ์์ํ๊ฒ ์ต๋๋ค.
ํ๋ฆฌํํ ๋ง
์ด์ question/templates/_list.php
์ ์๋ ํ์ด์ง๊ฐ ๋๋ ๋ชฉ๋ก๊ณผ ํ์ด์ง ๋ชฉ๋ก๊ฐ์ ๊ฒ๋ค์ ์ถ๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ฐ๋ฆฌ๋ ๋ฐ๋ณต์ ์ธ ์ผ์ ์ซ์ดํ๊ธฐ ๋๋ฌธ์ ํ์ด์ง ๊ด๋ จ๋ ์ฝ๋๋ฅผ ์กฐ๊ฐ ํ
ํ๋ฆฟ์์ ์ฌ์ฉ์ ํฌํผ ๋ก ๋ง๋ค๋๋ก ํ๊ฒ ์ต๋๋ค. ํฌํผ๋ link_to()
๋ format_date()
๊ฐ์ด ํ
ํ๋ฆฟ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ PHP ํจ์๋ค์
๋๋ค.
askeet/apps/frontend/lib/helper
์ GlobalHelper.php
ํ์ผ์ ๋ง๋ค๊ณ ๋ค์์ ์
๋ ฅํ์ญ์์ค.
<?php function pager_navigation($pager, $uri) { $navigation = ''; if ($pager->haveToPaginate()) { $uri .= (preg_match('/\?/', $uri) ? '&' : '?').'page='; // First and previous page if ($pager->getPage() != 1) { $navigation .= link_to(image_tag('first.gif', 'align=absmiddle'), $uri.'1'); $navigation .= link_to(image_tag('previous.gif', 'align=absmiddle'), $uri.$pager->getPreviousPage()).' '; } // Pages one by one $links = array(); foreach ($pager->getLinks() as $page) { $links[] = link_to_unless($page == $pager->getPage(), $page, $uri.$page); } $navigation .= join(' ', $links); // Next and last page if ($pager->getPage() != $pager->getCurrentMaxLink()) { $navigation .= ' '.link_to(image_tag('next.gif', 'align=absmiddle'), $uri.$pager->getNextPage()); $navigation .= link_to(image_tag('last.gif', 'align=absmiddle'), $uri.$pager->getLastPage()); } } return $navigation; }
ํ์ด์ง ๋ชฉ๋ก ํฌํผ๋ ์ด์ ์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์ฝ๋๋ณด๋ค ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค. ์ด๋ ํ ๋ผ์ฐํ
๊ท์น์ด๋ผ๋ ์ ์ฉ์ด ๊ฐ๋ฅํ๊ณ , ์ฒซ ํ์ด์ง์ผ ๊ฒฝ์ฐ์ '์ด์ ' ๋งํฌ๋ฅผ ํ์ํ์ง์์ผ๋ฉฐ ๋ง์ง๋ง ํ์ด์ง์ผ ๊ฒฝ์ฐ์๋ '๋ค์' ๋งํฌ๋ฅผ ํ์ํ์ง ์์ต๋๋ค. ๋ ์ฐ๋ฆฌ๋ ๋ค๊ฐ์ง ์ด๋ฏธ์ง (first.gif
, previous.gif
, 'next.gif๊ทธ๋ฆฌ๊ณ
last.gif`) ๋ฅผ ์ถ๊ฐํ์ฌ ๋งํฌ๋ค์ด ์ด์๊ฒ ๋ณด์ฌ์ง๋๋ก ํ์ต๋๋ค. askeet SVN ์ ์ฅ์ ์์ ์ด๋ค ์ด๋ฏธ์ง๋ฅผ ๋ค์ด ๋ฐ์ผ์ญ์์ค. ์๋ง ์ฌ๋ฌ๋ถ๋ค์ ์ดํ์ ์ฌ๋ฌ๋ถ ์์ ์ ํ๋ก์ ํธ์์ ์ ํฌํผ๋ฅผ ์ฌ์ฉํ์ค ์ ์์ผ์ค ๊ฒ๋๋ค.
question/templates/_list.php
์กฐ๊ฐ์ ์ด ํฌํผ๋ฅผ ์ฌ์ฉํ์๊ธฐ ์ํด์๋ ํฌํผ ํ์
์ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํด์ผ ํฉ๋๋ค.
<?php use_helper('Text', 'Global') ?> <?php foreach($question_pager->getResults() as $question): ?> <div class="question"> <div class="interested_block"> <?php include_partial('interested_user', array('question' => $question)) ?> </div> <h2><?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?></h2> <div class="question_body"> <?php echo truncate_text($question->getBody(), 200) ?> </div> </div> <?php endforeach; ?> <div id="question_pager"> <?php echo pager_navigation($question_pager, 'question/list') ?> </div>
์ด์ ์ฐ๋ฆฌ๋ ํ๋ ์ด์์ ํฌํผ๊ฐ ํ์ํ๊ธฐ๋๋ฌธ์ use_helper()
๋์ use_helper()
๊ฐ ์ฌ์ฉ๋๋ค๋ ์ ์ ์ฃผ์ํ์ญ์์ค. Global
์ด๋ผ๋ ์ด๋ฆ์ GlobalHelper.php
๋ผ๋ ์ด๋ฆ์ผ๋ก ์ฐ๊ฒฐ๋๋๋ก ๋์ด ์์ต๋๋ค.
์๋ ์ฃผ์๋ฅผ ํธ์ถํด์ ๊ธฐ๋ฅ์ด ์ ์์๋ํ๋์ง ์ดํ๋ณด์ญ์์ค.
http://askeet/frontend_dev.php/
์ต๊ทผ ์ง๋ฌธ ๋ชฉ๋ก
question
๋ชจ๋์ recent
์ก์
์ ์์ฑํฉ๋๋ค.
public function executeRecent() { $this->question_pager = QuestionPeer::getRecentPager($this->getRequestParameter('page', 1)); }
๊ฐ๋จํ์ฃ ? ์ฐ๋ฆฌ๋ ์ต๊ทผ ์ง๋ฌธ๋ค์ ๋ชฉ๋ก์ ๊ฒ์ํ๋ ๊ฒ์ QuestionPeer
์ ๋ชซ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. -Peer
ํด๋์ค๋ค์ ํด๋น ํด๋์ค์ ๊ฐ์ฒด๋ค์ ๋ฐํํ๋๋ก ์ค๊ณ๋์ด ์์ต๋๋ค. (์์ธํ ์ฌํญ์ ์จ๋ผ์ธ ๋ฌธ์๋ค ์ค ๋ชจ๋ธ ๋ถ๋ถ ์์ ์ดํด๋ณด์ค ์ ์์ต๋๋ค.) ํ์ง๋ง getRecentPager()
ํด๋์ค ๋ฉ์๋๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. askeet/lib/model/QuestionPeer.php
ํด๋์ค๋ฅผ ์ด๊ณ ๋ค์์ ์ถ๊ฐํฉ๋๋ค.
public static function getRecentPager($page) { $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max')); $c = new Criteria(); $c->addDescendingOrderByColumn(self::CREATED_AT); $pager->setCriteria($c); $pager->setPage($page); $pager->setPeerMethod('doSelectJoinUser'); $pager->init(); return $pager; }
๋ง์ง๋ง์ผ๋ก ์ฌ๋ผ์จ ์ง๋ฌธ์ด ๋จผ์ ์ฌ๋ผ์ค๋๋ก ์์ฑ์ผ์ ๊ธฐ์ค์ผ๋ก ํ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ ํฉ๋๋ค. ์ด ๋ฉ์๋๋ ๊ฐ์ฒด ํจ์๊ฐ ์๋ ํด๋์ค ํจ์์ด๊ธฐ ๋๋ฌธ์ parent
๋์ ์ self
๋ฅผ ์ฌ์ฉํฉ๋๋ค (์ฃผ - ์ด ๋ฉ์๋๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ์ดํ์ ->getRecentPager()
ํํ๋ก ํธ์ถ๋๋๊ฒ์ด ์๋๋ผ QuestionPeer::getRecentPager()
ํํ๋ก ํธ์ถ๋ฉ๋๋ค. ๋ฐ๋ผ์ $this
๋ parent
๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค). doSelect()
๋์ ์ doSelectJoinUser
๋ฅผ ์ฌ์ฉํ ์ด์ ๋ ์ง๋ฌธํ ์ฌ๋์ ๋ํ ์์ธํ ์ ๋ณด๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ธฐ์กด์๋ ์ง๋ฌธ ๋ชฉ๋ก์ ๋จผ์ ์ง์ํ๊ณ , ๊ฐ ์ง๋ฌธ์ ๋ํด์ ์ฌ์ฉ์์ ์์ธํ ์ ๋ณด๋ฅผ ๋ค์ ์ง์ํ์์ต๋๋ค. doSelectJoinUser()
๋ฉ์๋๋ ํ๋์ ์ง์๋ก ๋์ผํ ์์
์ ์ํํฉ๋๋ค. ์ด์ ์ฐ๋ฆฌ๊ฐ ์๋ ์ฝ๋๋ฅผ ์ํํด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ง์ํ์ง ์๊ฒ ๋ฉ๋๋ค.
$question->getUser();
joinUser
๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ง์์ ์๋ฅผ 1 + ์ง๋ฌธ ๊ฐฏ์์์ ํ๋๋ก ์ค์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๊ณ ๋ง์ํ ๊ฒ๋ง ๊ฐ์ต๋๋ค.
Propel ๋ฌธ์๋ค ์ ๋ณด์๋ฉด ์ด๋ฐ ๋ฉ์ง ๊ธฐ๋ฅ์ ๋ํ ์์ธํ ์ค๋ช ์ด ์์ต๋๋ค.
์ต๊ทผ ์ง๋ฌธ ๋ชฉ๋ก ํ
ํ๋ฆฟ์ ๋ฉ์ธํ์ด์ง์ ์ฌ๋ผ๊ฐ๋ ์ง๋ฌธ๋ชฉ๋ก๊ณผ ๋งค์ฐ ์ ์ฌํ ๊ฒ์
๋๋ค. askeet/apps/frontend/module/question/templates/recentSuccess.php
ํ์ผใ
๋ฅด ๋ง๋ค๊ณ ์๋ ๋ด์ฉ์ ์ถ๊ฐํ์ญ์์ค.
<h1>recent questions</h1> <?php include_partial('list', array('question_pager' => $question_pager)) ?>
์ด์ ์ ์ฐ๋ฆฌ๊ฐ 5์ผ์งธ ์ ์ง๋ฌธ ๋ชฉ๋ก์ ๋ฆฌํฉํ ๋งํ์๋์ง ์ดํดํ์ค ์ ์์ผ์ค ๊ฒ์
๋๋ค. ๋ง์ง๋ง์ผ๋ก frontend/config/routing.yml
ํ์ผ์, 4์ผ์งธ ํ๋ ๊ฒ์ฒ๋ผ, recent_question
๊ท์น์ ์ถ๊ฐํฉ๋๋ค.
recent_questions: url: /question/recent/:page param: { module: question, action: recent, page: 1 }
์ ๊น๋ง์. question/_list
์กฐ๊ฐ ํ์ผ์ question/list
๋ผ์ฐํ
๊ท์น์ ์ด์ฉํ์ฌ ํ์ด์ง๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์, ์ต๊ทผ ์ง๋ฌธ ๋ชฉ๋ก์์๋ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ ๊ฒ์
๋๋ค. ๋ผ์ฐํ
๊ท์น์ ์กฐ๊ฐํ์ผ์ ์ธ์ํํ๋ก ๋๊ฒจ์ฃผ๋๋ก ํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค. recentSuccess.php
์ ๋ง์ง๋ง ๋ถ๋ถ๋ฅใน ๋ค์๊ณผ ๊ฐ์ด ์์ ํฉ๋๋ค.
<?php include_partial('list', array('question_pager' => $question_pager, 'rule' => 'question/recent')) ?>
list.php
์กฐ๊ฐํ์ผ์ ๋ง์ง๋ง ์ค ์ญ์ ์์ ํฉ๋๋ค.
<div id="question_pager"> <?php echo pager_navigation($question_pager, $rule) ?> </div>
modules/question/templates/listSuccess.php
ํ์ผ์์ _list
์กฐ๊ฐํ์ผ์ ํธ์ถํ๋ ๋ถ๋ถ์ ๋ผ์ฐํ
๊ท์น ์ธ์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋ ์์ง ๋ง์๊ธฐ ๋ฐ๋๋๋ค.
<h1>popular questions</h1> <?php echo include_partial('list', array('question_pager' => $question_pager, 'rule' => 'question/list')) ?>
์บ์ฌ๋ฅผ ์ญ์ ํ๋ฉด (์ค์ ํ์ผ์ด ๋ณ๊ฒฝ๋์์ต๋๋ค) ๋์ ๋๋ค.
์ด์ ์ต๊ทผ ์ง๋ฌธ๋ชฉ๋ก์ ํ์ํ์๋ ค๋ฉด ์๋ URL ๋ก ์ ์ํ์๋ฉด ๋ฉ๋๋ค.
http://askeet/recent
์ต๊ทผ ๋ต๋ณ ๋ชฉ๋ก
๋ฐฉ๊ธ ํ ๊ฒ๊ณผ ๊ฑฐ์ ๋น์ทํ๊ธฐ ๋๋ฌธ์, ๋นจ๋ฆฌ ์งํํ๋๋ก ํ๊ฒ ์ต๋๋ค.
answer
๋ชจ๋์ ์์ฑํฉ๋๋ค.$ symfony init-module frontend answer
recent
์ก์ ์ ์์ฑํฉ๋๋ค.public function executeRecent() { $this->answer_pager = AnswerPeer::getRecentPager($this->getRequestParameter('page', 1)); }
AnswerPeer
ํด๋์ค๋ฅผ ํ์ฅํฉ๋๋ค.public static function getRecentPager($page) { $pager = new sfPropelPager('Answer', sfConfig::get('app_pager_homepage_max')); $c = new Criteria(); $c->addDescendingOrderByColumn(self::CREATED_AT); $pager->setCriteria($c); $pager->setPage($page); $pager->setPeerMethod('doSelectJoinUser'); $pager->init(); return $pager; }
recentSuccess.php
ํ ํ๋ฆฟ์ ๋ง๋ญ๋๋ค.<?php use_helper('Date', 'Global') ?> <h1>recent answers</h1> <div id="answers"> <?php foreach ($answer_pager->getResults() as $answer): ?> <div class="answer"> <h2><?php echo link_to($answer->getQuestion()->getTitle(), 'question/show?stripped_title='.$answer->getQuestion()->getStrippedTitle()) ?></h2> <?php echo count($answer->getRelevancys()) ?> points posted by <?php echo link_to($answer->getUser(), 'user/show?id='.$answer->getUser()->getId()) ?> on <?php echo format_date($answer->getCreatedAt(), 'p') ?> <div> <?php echo $answer->getBody() ?> </div> </div> <?php endforeach ?> </div> <div id="question_pager"> <?php echo pager_navigation($answer_pager, 'answer/recent') ?> </div>
๋ธ๋ผ์ฐ์ ์์ ํ ์คํธํฉ๋๋ค.
http://askeet/answer/recent
์ข ์ต์ํด์ง์๊ณ ๊ณ์ ๊ฐ์?
์ฐธ๊ณ : 4์ผ์งธ ์๋ ์์ธํ ๋ต๋ณ์ ์ถ๋ ฅํ๋๋ฐ์ ๊ฐ์ ์ฝ๋๊ฐ ์ฌ์ฉ๋์๋๊ฑธ ๋์น์ฑ์ จ๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ด ์ฝ๋๊ฐ ์ต์ํ ๋ ๊ตฐ๋ฐ์ ์ฐ์๊ธฐ๋๋ฌด๋น, ์ด๋ฅผ
_answer.php
์กฐ๊ฐํ์ผ๋ก ์ฎ๊ธฐ๊ฒจ์question/show
์answer/recent
์ ์ฌ์ฉํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์์ธํ ์ฌํญ์ askeet SVN ์ ์ฅ์ ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
์ฌ์ฉ์ ํ๋กํ
์ง๋ฌธ์ ์ถ๋ ฅ๋๋ ์ฌ์ฉ์ ์ด๋ฆ์, ์์ง ์์ฑ๋์ง ์์์ง๋ง, user/show
์ก์
์ผ๋ก ์ฐ๊ฒฐ๋ ๊ฒ์
๋๋ค. ์ด ํ์ด์ง๋ ์ฌ์ฉ์ ํ๋กํ ํ์ด์ง๋ก, ์ฌ์ฉ์์ ๊ดํ ๋ช๊ฐ์ง ์์ธํ ์ฌํญ๊ณผ ํจ๊ป ์ฌ์ฉ์๊ฐ ์์ฑํ ์ต๊ทผ ์ง๋ฌธ๋ค๊ณผ ๋ต๋ณ๋ค์ ์ถ๋ ฅํ ๊ฒ์
๋๋ค.
์ฒซ๋ฒ์งธ๋ก ํ ์ผ์ ์ก์ ์ ์์ฑํ๋ ์ผ์ ๋๋ค.
public function executeShow() { $this->subscriber = UserPeer::retrieveByPk($this->getRequestParameter('id', $this->getUser()->getSubscriberId())); $this->forward404Unless($this->subscriber); $this->interests = $this->subscriber->getInterestsJoinQuestion(); $this->answers = $this->subscriber->getAnswersJoinQuestion(); $this->questions = $this->subscriber->getQuestions(); }
->getInterestsJoinQuestion()
๊ณผ ->getAnswerJoinQuestion()
๋ฉ์๋๋ค์ User
ํด๋์ค์ ๊ธฐ๋ณธ ๋ฉ์๋๋ค์
๋๋ค. askeet/lib/model/om/BaseUser.php
ํด๋์ค๋ฅผ ๋ณด์๋ฉด ์ด๋ป๊ฒ ๋์ํ๋์ง ํ์ธํ์ค ์ ์์ผ์ค ๊ฒ์
๋๋ค.
askeet/apps/frontend/modeules/user/templates/showSuccess.php
ํ
ํ๋ฆฟ์ ์ฝ๊ฒ ๋ง๋์ค ์ ์์ผ์ค ๊ฒ์
๋๋ค.
<h1><?php echo $subscriber ?>'s profile</h1> <h2>Interests</h2> <ul> <?php foreach ($interests as $interest): $question = $interest->getQuestion() ?> <li><?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?></li> <?php endforeach; ?> </ul> <h2>Contributions</h2> <ul> <?php foreach ($answers as $answer): $question = $answer->getQuestion() ?> <li> <?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?><br /> <?php echo $answer->getBody() ?> </li> <?php endforeach; ?> </ul> <h2>Questions</h2> <ul> <?php foreach ($questions as $question): ?> <li><?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?></li> <?php endforeach; ?> </ul>
๋ฌผ๋ก User
๊ฐ์ฒด์ ->getInterestsJoinQuestion()
์ด๋ ->getAnswersJoinQuestion()
, getQuestion()
๋ฉ ์ฌ๊ธฐ์ ์ถ๋ ฅ๋๋ ๊ฒฐ๊ณผ์ ๊ฐฏ์๋ ์ ๋ ฌ์์๋ฅผ ๋ฐ๊พธ๊ณ ์ถ์ผ์ค ๊ฒ์
๋๋ค. ์ด๊ฒ๋ค์ askeet/lib/model/User.php
ํด๋์ค์์ ์ด๋ค ๋ฉ์๋๋ค์ ์ฌ์ ์ (override) ํจ์ผ๋ก์จ ๊ฐ๋ฅํฉ๋๋ค. ์ด๋ฅผ ์ด๋ป๊ฒ ํ๋์ง๋ ์ฌ๊ธฐ์ ๊ณต๊ฐํ์ง ์๊ฒ ์ง๋ง ์ค๋์ ์์ค์ฝ๋์์๋ ํ์ธ๊ฐ๋ฅํ์ค ๊ฒ์
๋๋ค.
์ ์ด์ ๋ง์ง๋ง ํ ์คํธ๋ฅผ ํ ์๊ฐ์ ๋๋ค. ์ฒซ๋ฒ์งธ ์ฌ์ฉ์๊ฐ ๋ฌด์์ ํ๋์ง ๋ณด๊ฒ ์ต๋๋ค.
http://askeet/user/show/id/1
์ฌ์ฉ์ ํ๋กํ์ ์ง๋ฌธ์์๋ ์ฐ๊ฒฐ๋ ์ ์์ต๋๋ค. question/templates/showSuccess.php
์ /question/templates/_list.php
์ question_body
๋ฌธ๋จ์ ์ฒซ๋ถ๋ถ์ ๋ค์ ์ค์ ์ถ๊ฐํ์ญ์์ค.
<div>asked by <?php echo link_to($question->getUser(), 'user/show?id='.$question->getUser()->getId()) ?> on <?php echo format_date($question->getCreatedAt(), 'f') ?></div>
_list.php
ํ์ด์ง์ Date
ํฌํผ ์ฌ์ฉ์ ๋ช
์ํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.
๋ค๋น๊ฒ์ด์ ๋ฐ ๋ฌ๊ธฐ
๊ธ๋ก๋ฒ ๋ ์ด์์์ ์์ ํ์ฌ ์ํ๋ฐ๋ฅผ ๋ฃ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด ๋ฐ์๋ ๋์ ์ธ ๋ด์ฉ์ด ๋ค์ด๊ฐ ๊ฒ์ด์ง๋ง, ๊ฐ๊ฐ์ ํ ํ๋ฆฟ์ ๋ค์ด๊ฐ๊ธฐ๋ณด๋ค๋ ๋ ์ด์์์ ํ ์๋ฆฌ๋ฅผ ์ฐจ์งํ๋๋ก ํ ๊ฒ์ ๋๋ค. ๋ง๋ถ์ฌ์ ํ ํ๋ฆฟ์ ๋ฐ ๊ด๋ จ ์ฝ๋๋ฅผ ๋ฃ๋ ๊ฒ์ ๋ฐ๋ณต์ ์ธ ์์ ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฐ๊ฒ ์ซ์ดํ๋ค๋ ๊ฒ์ ์ ์์๊ฒ ์ฃ ?
๊ทธ๊ฒ์ด ์ ๋ฐ๊ฐ ์ปดํฌ๋ํธ๊ฐ ๋์ด์ผ ํ๋์ง์ ๊ดํ ์ด์ ์ ๋๋ค. ์ปดํฌ๋ํธ๋ ํ๋์ ์ก์ ์ ๊ฒฐ๊ณผ๊ฐ (์๋ฅผ ๋ค๋ฉด ํ ํ๋ฆฟ ์คํ์ ๊ฒฐ๊ณผ๋ก HTML ์ฝ๋๊ฐ ํ์ฑ๋ฉ๋๋ค) ๋ณ์ ํํ๋ก ์ ์ฅ๋๋ ๊ฒ์ ๋๋ค. ์จ๋ผ์ธ ๋ฌธ์์ค ๋ทฐ ๋ถ๋ถ ์ ์ปดํฌ๋ํธ๊ฐ ๋ฌด์์ด๊ณ , ์กฐ๊ฐํ์ผ๊ณผ ์ปดํฌ๋ํธ๊ฐ ์ด๋ป๊ฒ ๋ค๋ฅธ์ง๊ฐ ์ค๋ช ๋์ด ์์ต๋๋ค.
๋ ์ด์์์ ์ปดํฌ๋ํธ ์ถ๊ฐํ๊ธฐ
๊ธ๋ก๋ฒ ๋ ์ด์์ (askeet/apps/frontend/templates/layout.php
) ์ ์ฝ๋๋ค. ์ด ๋ถ๋ถ ๊ธฐ์ต๋์๋์?
<div id="content_bar"> <!-- Nothing for the moment --> <div class="verticalalign"></div> </div>
์ฃผ์ ๋ถ๋ถ์ ์๋์ ๊ฐ์ด ์์ ํฉ๋๋ค.
<?php include_component_slot('sidebar') ?>
์ด์์ ๋๋ค.
์ปดํฌ๋ํธ์ ์ด๋ค ์ก์ ์ด ๋ค์ด๊ฐ์ง ์ ํ๊ธฐ
์ฐ๋ฆฌ๋ ๋จ์ํ ์ปดํฌ๋ํธ ๋ณด๋ค๋ ์ข ๋ ๊ฐ๋ ฅํ ์ปดํฌ๋ํธ ์ฌ๋กฏ์ ์ฌ์ฉํ๊ธฐ๋ก ํ์์ต๋๋ค. ์ปดํฌ๋ํธ ์ฌ๋กฏ์ ์ด๋ ํ ์ก์
์์ ํธ์ถ๋์ด์ง๋๋์ ๋ฐ๋ผ์ ํ๋์ด ๋ณ๊ฒฝ๋๋ ์ปดํฌ๋ํธ๋ฅผ ๋งํฉ๋๋ค. ๋ทฐ ์ค์ ํ์ผ (view.yml
) ์์ ์ปดํฌ๋ํธ ์ฌ๋กฏ์ด ์ด๋ ํ ์ก์
๊ณผ ์ฐ๊ฒฐ๋์ด์ ธ์ผ ํ๋์ง๋ฅผ ์ ์ํฉ๋๋ค.
default: components: sidebar: [sidebar, default]
์ด ์์ ์์๋, sidebar
๋ผ๋ ์ปดํฌ๋ํธ ์ฌ๋กฏ์ด sidebar
๋ชจ๋์ default
์ก์
๊ณผ ์ฐ๊ฒฐ๋๋๋ก ์ ์๋์์ต๋๋ค.
๋ทฐ ์ค์ ์ ์ ์ฒด ์ดํ๋ฆฌ์ผ์ด์
์ ์ํด ์ ์๋๊ฑฐ๋ (askeet/apps/frontend/config/
๋๋ ํ ๋ฆฌ) , ํ๋์ ๋ชจ๋๋ง์ ์ํด ์ ์๋ ์ ์์ต๋๋ค (askeet/apps/frontend/modules/mymodule/config
๋๋ ํ ๋ฆฌ). ์ฐ๋ฆฌ๋ ์ ์ฒด ์ดํ๋ฆฌ์ผ์ด์
์ ์ํด ์ ์ํ๊ณ , ํ์ํ ๊ฒฝ์ฐ ์ฌ์ ์ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
askeet/apps/frontend/config/view.yml
ํ์ผ์ ์ด๊ณ ์์ ์ค์ ๋ด์ฉ์ ์ ์ฅํฉ๋๋ค. ์จ๋ผ์ธ ๋ฌธ์๋ค์ค ๊ด๊ณ๋ ๋ถ๋ถ ์์ ์ข ๋ ์์ธํ ๋ด์ฉ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
sidebar/default
์ก์
๊ณผ ํ
ํ๋ฆฟ ์์ฑํ๊ธฐ
๋จผ์ sidebar
๋ชจ๋์ ์์ฑํฉ๋๋ค.
$ symfony init-module frontend sidebar
๋ค์์ผ๋ก default
์ปดํฌ๋ํธ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. askeet/apps/frontend/modules/sidebar/actions/
๋๋ ํ ๋ฆฌ์ actions.class.php
๋ฅผ components.class.php
๋ก ์์ ํ๊ณ , ๋ด์ฉ์ ์๋์ ๊ฐ์ด ์์ ํฉ๋๋ค.
<?php class sidebarComponents extends sfComponents { public function executeDefault() { } }
์ปดํฌ๋ํธ ๋ทฐ ์ญ์ ๋ค๋ฅธ ์ก์
๋ค์ ํ
ํ๋ฆฟ๊ณผ ๊ฐ์ ํ
ํ๋ฆฟ์
๋๋ค. ๋ค๋ฅธ์ ์ ์ด๋ฆ์ง๋ ๋ฐฉ์์
๋๋ค. ์ปดํฌ๋ํธ ๋ทฐ๋ ์ผ๋ฐ ํ
ํ๋ฆฟ์ฒ๋ผ Success
๋ฑ์ผ๋ก ๋๋์ง ์๊ณ ์กฐ๊ฐํ์ผ์ฒ๋ผ _
๋ก ์์ํฉ๋๋ค. ๋ฐ๋ผ์ askeet/apps/frontend/modules/sidebar/templates/_default.php
ํ์ผ์ ๋ง๋ค๊ณ (๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ๋์ง ์์ indexSuccess.php
ํ์ผ์ ์ง์ฐ์ญ์์ค) ๋ค์ ๋ด์ฉ์ ์
๋ ฅํ์๊ธฐ ๋ฐ๋๋๋ค.
<?php echo link_to('ask a new question', 'question/add') ?> <ul> <li><?php echo link_to('popular questions', 'question/list') ?> <li><?php echo link_to('latest questions', 'question/recent') ?></li> <li><?php echo link_to('latest answers', 'answer/recent') ?></li> </ul>
๋ง์ฝ ์ฌ๋ฌ๋ถ์ askeet ์น์ฌ์ดํธ์์ ๋น์ฅ ๋ค๋น๊ฒ์ด์
์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ค๋ฉด ์๋ฌ๋ฅผ ๋ง๋์ค ๊ฒ์
๋๋ค. ๊ทธ๊ฒ์ ์ฌ๋ฌ๋ถ์ธ ์ค์ ๋ค์ด ์บ์ฌ๋๋ ์์ ๋ฒ์ (production) ์ ์น์ฌ์ดํธ๋ฅผ ๋ณด์๊ณ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์์ ๋ฒ์ ์์๋ ์์ ํ view.yml
์ด๋ผ๋ ์ค์ ํ์ผ์ด ์์ง ํจ๋ ฅ์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ณ๊ฒฝ์ฌํญ์ ๋ณด์๊ณ ์ถ์ผ์๋ค๋ฉด ์บ์ฌ๋ฅผ ์ง์ฐ๋์ง ์๋๋ฉด ๊ฐ๋ฐ๋ฒ์ ์ ์ฌ์ฉํ์
์ผ ํฉ๋๋ค.
$ symfony clear-cache
๋๋
http://askeet/frontend_dev.php/
๋ค๋น๊ฒ์ด์ ๋ฐ๊ฐ ๋ชจ๋ ํ์ด์ง์์ ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ๋ณด์ค ์ ์์ต๋๋ค.
์ฐธ๊ณ : ์ด๊ฒ์ ์์ ๋ฒ์ ์ ์ผ๋ฐ์ ์ธ ํจ๊ณผ์ ๋๋ค. ๋ฐ๋ผ์ ์ค์ ํ์ผ ์์ ์ด ๋น๋ฒํ ๊ฐ๋ฐ๋์ค์๋ ๊ฐ๋ฐํ๊ฒฝ์ ์ฌ์ฉํ์๊ณ , ์ค์ ํ์ผ์ด ๋ฐ๋ ์ดํ์ ์์ ๋ฒ์ ์ ํตํด ์น์ฌ์ดํธ๋ฅผ ๋๋ฌ๋ณด๊ณ ์ถ์ผ์๋ค๋ฉด ์บ์ฌ๋ฅผ ์ง์ฐ์ ์ผ ํฉ๋๋ค.
์ข ๋ ์์ธํ ๋ทฐ ์ค์
apps/config/
์ view.yml
ํ์ผ์ ์ข ๋ ๋๋ฌ๋ณด๊ฒ ์ต๋๋ค.
default: http_metas: content-type: text/html; charset=utf-8 metas: title: symfony project robots: index, follow description: symfony project keywords: symfony, project language: en stylesheets: [main, layout] javascripts: [] has_layout: on layout: layout components: sidebar: [sidebar, default]
metas
๋ถ๋ถ์ ์ ์ฒด ์ฌ์ดํธ์ ๊ดํ ๋ฉํํ๊ทธ๊ด๋ จ ์ค์ ์ด ๋ชจ๋ ๋ค์ด์์ต๋๋ค. title
ํค๋ ๋ธ๋ผ์ฐ์ ์๋์ฐ์ ์ถ๋ ฅ๋ ์ ๋ชฉ์ด ์ ์ฅ๋์ด ์์ต๋๋ค. ํ์ดํ์ ๊ฒ์์์ง์ด ๊ฐ์ฅ ๋จผ์ ํ์ธํ๋ ๊ฒ์ด๋ฏ๋ก ๊ต์ฅํ ์ค์ํฉ๋๋ค. ๋ฐ๋ผ์ askeet ์น ์ฌ์ดํธ๋ฅผ ์ข ๋ ์ ๋ํ๋ด๋ ๊ฒ์ผ๋ก ๋ณ๊ฒฝํ๋๋ก ํ๊ฒ ์ต๋๋ค.
metas: title: askeet! ask questions, find answers robots: index, follow description: askeet!, a symfony project built in 24 hours keywords: symfony, project, askeet, php5, question, answer language: en
ํ์ฌ ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจ ํ์ญ์์ค. ๋ง์ฝ ๋ณ๊ฒฝ์ฌํญ์ด ๋ณด์ด์ง ์๋๋ค๋ฉด, ์์ ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ๊ณ์๋ฉฐ ์บ์ฌ๋ฅผ ์ง์ฐ์์ง ์์ผ์ ๊ฒ์ ๋๋ค.
์ฐธ๊ณ : ํ๋ก์ ํธ ํ์ด์ง์ ๊ธฐ๋ณธ ์ ๋ชฉ ์ด์ธ์๋, ์ฌํฌ๋๋
robots.txt
์favicon.ico
๋ฅผ ์น ๋๋ ํ ๋ฆฌ (askeet/web/
) ์ ์์ฑํฉ๋๋ค. ์ด๋ค๋ ์์ ํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.์ฐธ๊ณ : ๊ฐ ํ์ด์ง๋ง๋ค ํ์ด์ง ์ ๋ชฉ์ ๋ฐ๊พธ์ ์ผ ํ ์ง๋ ๋ชจ๋ฆ ๋๋ค. ๊ฐ ๋ชจ๋๋ง๋ค
view.yml
์ค์ ํ์ผ์ ์์ฑํ์ ์ ํ์ค์๋ ์์ง๋ง, ์ด๋๊น์ง๋ ํ์ด์ง ์ ๋ชฉ์ด ์ ์ ์ธ ๊ฒ์ ๋ง์ฐฌ๊ฐ์ง ์ ๋๋ค.->setTitle()
๋ฉ์๋๋ฅผ ์ด์ฉํ์๋ฉด ๋์ ์ผ๋ก ์ ๋ชฉ์ ์ค์ ํ์ค ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ์จ๋ผ์ธ ๋ฌธ์์ค ๋ทฐ ์ค์ ๋ถ๋ถ ์ ์ฐธ๊ณ ํ์ญ์์ค.[php] $this->getResponse()->setTitle($title);
์ง๋ ์ค๊ฑฐ๋ฆฌ
์ด์ 7์ผ์งธ์ด๋, ์ ์ ๋ฉ์ถฐ์ ๊ทธ๋์ ์ฐ๋ฆฌ๊ฐ ๋ฌด์์ ํด ์๋์ง ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ํ์ฌ์ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ํฌํจํด์ ์ฌ์ฉ๊ฐ๋ฅํ ์ก์ ๋ค์ด ๋ฌด์์ด ์๋์ง ๊ฐ์ ๊ฒ๋ค์ ๋ํด์ ๊ธฐ๋ก์ ๋จ๊ฒจ๋ ์ข์ ๊ธฐํ์ด๊ธฐ๋ ํฉ๋๋ค.
์ฌ์ค, ์ฌ๋ฌ๋ถ์ ์ฝ๋ฉ์ ํ๊ณ ์๋ ๋์์ ๋ฌธ์๋ฅผ ๋จ๊ฒจ์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๊ฐ๊ฐ์ ๋ฉ์๋์ PHP doc ์คํ์ผ๋ก ์ฃผ์์ ๋จ๋ค๋๊ฐ ํ๋ ๊ฒ์ฒ๋ผ ๋ง์
๋๋ค. ์ฌํฌ๋ ํ๋ก์ ํธ๋ ๊ฐ ๋ฉ์๋๋ ํจ์๋ค์ ์ด๋ฆ์ด ๊ทธ๊ฒ์ด ํ๋์ผ์ ๋ํ ์ค๋ช
์ ์ ๊ณตํ๊ธฐ๋ ํฉ๋๋ค. ๋ฉ์๋๋ค์ด ์งง๊ณ ๋งค์ฐ ์ฝ๊ธฐ ํธํ๊ฒ ๋์ด์์ต๋๋ค. ๋ง์ ๊ฒฝ์ฐ์, ํ
ํ๋ฆฟ๋ค์ foreach
์ if
๊ตฌ๋ฌธ๋ง์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํด๋น ๊ธฐ๋ฅ์ ํ์
ํ๊ธฐ๊ฐ ์ฝ์ต๋๋ค. ๊ทธ๊ฒ์ด askeet SVN ์ ์ฅ์ ์ ์ฝ๋๋ค์ด ์ฃผ์์ ๋ง์ด ํฌํจํ๊ณ ์์ง ์์ ์ด์ ์
๋๋ค. ๋ง๋ถ์ฌ์ 7์๊ฐ๋์ ์ฐ๋ฆฌ๊ฐ ๋ฌด์์ ํ๋์ง์ ๋ํด์ ์ค๋ช
์ ์์ฑํ๊ธฐ๋ ํ๊ตฌ์.
์ ์ด์ ERD ๊ฐ ์ด๋ป๊ฒ ๋ฐ๋์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฌ์ฉ ๊ฐ๋ฅํ ์ก์ ๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
answer/ recent question/ list show recent sidebar/ default (component) user/ show login logout handleErrorLogin
๋ชจ๋ธ๋ค์ด ๊ฐ์ง๊ณ ์๋ ๋ฉ์๋๋ค์ ์๋์ ๊ฐ์ต๋๋ค.
Anwser() getRelevancyUpPercent() getRelevancyDownPercent() AnswerPeer:: getRecentPager() Interest-> save() Question-> setTitle() QuestionPeer:: getQuestionFromTitle() getHomepagePager() getRecentPager() Relevancy save() User-> __toString() setPassword() myUser-> signIn() signOut() getSubscriberId() getSubscriber() getNickName()
๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์ ๋๊ตฌ๋ค๊ณผ ์ฌ์ฉ์ ํผ๊ฐ ํ์ธ ํด๋์ค๋ askeet/apps/frontend/lib/
๋๋ ํ ๋ฆฌ์ ์์ต๋๋ค.
7์๊ฐ์น๊ณค ๋์์ง ์์ฃ ?
๋ด์ผ ์ด ์๊ฐ์
์ค๋์ ์ดํ๋ฆฌ์ผ์ด์ ์์ ์ด ๋ง์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ํ ๋น ๋ฅด๊ฒ ์งํ๋์์ต๋๋ค. ์ด์ ์ฌ์ฉ์-์ปดํจํฐ ์ํธ์์ฉ๊ฐ์ AJAX ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ชจ๋ ์ค๋น๊ฐ ๋์์ต๋๋ค. ๋ด์ผ์ AJAX ๋ฅผ ์ด์ฉํด์ ๋ก๊ทธ์ธํ๊ณ ์ง๋ฌธ์ ๋ํ ํ๋ฏธ๋๋ฅผ ์ถ๊ฐํ ์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค. ๋์น์ง ๋ง์ญ์์ค!
์ค๋์ ๋ชจ๋ ์ฝ๋๋ askeet SVN ์ ์ฅ์ ์์ release_day_7
ํ๊ทธ๋ก ๋ค์ด๋ก๋ ๊ฐ๋ฅํฉ๋๋ค. askeet ๋ฉ์ผ๋ง ๋ฆฌ์คํธ ์์ ๊ด์๋ณด๋ค ๋น ๋ฅธ ์๋๋ก ์ง๋ฌธ๋ค์ ๋ต๋ณํด๋๋ฆฌ๊ณ ์์ต๋๋ค.
This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.