배너 밑으로는 선전하고 싶은 상품 목록 4개를 열거한다. 이때 반응형 웹 디자인의 그리드(Grid)를 적용해 본다.
화면 분할
- WEB-INF/templates/layout/home.html 템플릿의 내용이 많아지면 partial html로 분리하여 include하는 방식을 취한다
- 우선, Homepage Banner Ad Carousel 부분을 <th:include> 처리하고 Product 목록 부분도 <th:include> 처리해 관리한다.
- 기존 화면
- 변경 화면
+ 박스 테두리 CSS를 적용한다
+ 각 박스 테두리별로 반응형 그리드를 적용한다
- WEB-INF/templates/layout/home.html 내역중 Carousel에 대한 부분과 product 목록에 대한 부분을 WEB-INF/templates 폴더 밑에 main/partials 폴더를 새롭게 만들고 banner-caruosel.html 과 product-list.html 을 생성하고 기존 내역을 옮긴다.
- content의 contentType인 "Homepage Featured Products Title" 인 목록을 뿌려주는 것이다.
- layout 폴더에서 main 폴더로 옮기는 이유는 해당 main 폴더 영역에 있는 부분이 계속 변경되기 때문이다. 즉, 다른 페이지로 이동해도 nav와 footer는 고정되어 있다.
// home.html의 과거 내역
<blc:content contentType="Homepage Featured Products Title" />
<div th:if="${contentItem !=null and contentItem['messageText'] !=null}" class="title_bar" th:text="${contentItem['messageText']}"></div>
<ul id="products" class="group">
<li th:each="product : ${products}" th:object="${product}" th:include="catalog/partials/productListItem" class="product_container"></li>
</ul>
// 신규 layout/home.html 일부 내역
<div th:include="main/partials/banner-carousel" />
<div class="section">
<div th:include="main/partials/featured-products" />
</div>
// main/partials/featured-products.html
<div class="container">
<div class="row">
<blc:content contentType="Homepage Featured Products Title" />
<div th:if="${contentItem !=null and contentItem['messageText'] !=null}"
class="col-lg-12 col-md-12 col-sm-12 col-xs-12 featured-title"
th:text="${contentItem['messageText']}"></div>
<div th:each="product : ${products}"
th:object="${product}"
th:include="catalog/partials/productListItem"
class="col-lg-3 col-md-3 col-sm-6 col-xs-6">
</div>
</div>
</div>
- class="col-lg-3 col-md-3 col-sm-6 col-xs-6" 을 적용해서 데스크톱에서는 4개씩 상품이 보이고 테블릿 이하는 2개씩 상품이 보임
Product Item 그리드 구성
- th:include="catalog/partials/productListItem" 에서 기존 productListItem.html 의 CSS를 하기와 같이 다시 적용한다
+ max-width: 320px; 를 주어 박스의 최대 크기를 지정한다.
// /webapp/css/style.css 일부 내역
/************************************/
/* featured product list */
/************************************/
.thumbnail {
max-width: 320px;
display: block;
padding: 5px;
margin-bottom: 10px;
line-height: 1.5;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
-webkit-transition: border .2s ease-in-out;
-o-transition: border .2s ease-in-out;
transition: border .2s ease-in-out;
}
.thumbnail .content {
padding: 3px;
font: 13px/18px 'BryantLGRegular';
color: #655c5a;
overflow: hidden;
}
.thumbnail .content .title {
font: 15px/18px 'BryantLGMedium';
margin-bottom: 7px;
color: #222222;
height: 36px;
max-height: 36px;
}
.thumbnail .content .desc {
padding: 3px;
font: 13px/18px 'BryantLGLight';
color: #655c5a;
overflow: hidden;
height: 72px;
max-height: 72px;
}
.thumbnail .new_badge {
width: 60px;
height: 60px;
background: url('../img/badge-new.png') no-repeat;
text-indent: -9999px;
position: absolute;
top: -10px;
left: -1px;
z-index: 20;
}
.thumbnail .image {
margin-bottom: 10px;
overflow: hidden;
position: relative;
z-index: 10;
}
.thumbnail .image .price {
position: absolute;
background-color: black;
color: white;
opacity: 0.8;
padding: 10px 20px;
font: 16px/16px 'BryantLGMedium';
font-weight: 600;
bottom: 5px;
right: 5px;
}
- 적용한 productListItem.html 의 내용은 하기와 같다.
<div class="thumbnail">
<div th:if="*{featuredProduct}" class="new_badge">New!</div>
<div class="image">
<a th:href="@{*{url}}">
<img th:if="*{media['primary']}" blc:src="@{*{media['primary'].url} + '?browse'}" th:alt="*{name}" />
<div class="price" th:if="${#object instanceof T(org.broadleafcommerce.core.catalog.domain.ProductBundle)}">
<div blc:price="*{salePrice}" th:if="*{onSale}" th:classappend="*{defaultSku.onSale}? 'sale'"></div>
<div blc:price="*{retailPrice}" th:classappend="*{onSale}? 'has-sale'"></div>
</div>
<div class="price" th:unless="${#object instanceof T(org.broadleafcommerce.core.catalog.domain.ProductBundle)}">
<div blc:price="*{defaultSku.salePrice}" th:if="*{defaultSku.onSale}" th:classappend="*{defaultSku.onSale}? 'sale'"></div>
<div blc:price="*{defaultSku.retailPrice}" th:classappend="*{defaultSku.onSale}? 'has-sale'"></div>
</div>
</a>
</div>
<div class="content">
<div class="title" th:text="*{name}">Product Name</div>
<p class="desc" th:utext="*{longDescription}">description</p>
<p>
<div th:class="*{'productActions productActions' + id}"
th:with="checkInventory=*{defaultSku.inventoryType?.type == 'CHECK_QUANTITY'},
availableInventory=${checkInventory ? #object.defaultSku.quantityAvailable != null and #object.defaultSku.quantityAvailable != 0 : true},
inCart=${cart.containsSku(#object.defaultSku) and #lists.isEmpty(product.productOptions)}">
<div th:if="${checkInventory and !availableInventory}" class="out_of_stock">
<a disabled="disabled" class="inCart">Out of Stock</a>
</div>
<div class="btn btn-default" th:classappend="${!inCart}? ' hidden'" th:if="${#lists.isEmpty(product.productOptions)}">
<a class="modalcart inCart" th:href="@{/cart}"><span th:text="#{product.inCart}">In Cart!</span></a>
</div>
<div class="add_to_cart" th:classappend="${inCart or !availableInventory}? ' hidden'">
<blc:form method="POST" th:action="@{/cart/add}">
<input type="hidden" name="productId" th:value="*{id}" />
<input type="hidden" name="quantity" value="1" />
<input type="hidden" name="hasProductOptions" th:value="*{!#lists.isEmpty(productOptions)}" />
<input type="submit" class="btn btn-primary" th:value="#{product.buyNow}"/>
</blc:form>
</div>
</div>
</p>
</div>
</div>
<div style="display: none;" th:id="*{'productOptions' + id}" class="product-options modal">
<h3 th:text="*{name}"></h3>
<div class="product-options" th:substituteby="catalog/partials/productOptions"/>
<input type="button" class="addToCart" th:value="#{product.buyNow}" />
</div>
화면 구성이 되었다면 다음으로 2단 메뉴 구성을 해보자
'Study Frameworks > BroadLeaf eCommerce' 카테고리의 다른 글
[BroadLeaf] Carousel 적용하기 - 3 (0) | 2014.12.14 |
---|---|
[BroadLeaf] Twitter Bootstrap 적용하기 - 2 (0) | 2014.12.03 |
[BroadLeaf] eCommerce 시작하기 - 1 (0) | 2014.12.03 |