Merge pull request #101 from thelia/frontend

Frontend
This commit is contained in:
Manuel Raynaud
2013-11-12 02:16:42 -08:00
31 changed files with 397 additions and 247 deletions

View File

@@ -58,6 +58,11 @@
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default> <default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account-password</default> <default key="_view">account-password</default>
</route> </route>
<route id="customer.order.pdf.delivery" path="/account/order/pdf/delivery/{order_id}">
<default key="_controller">Thelia\Controller\Front\OrderController::generateDeliveryPdf</default>
<requirement key="order_id">\d+</requirement>
</route>
<!-- end customer routes --> <!-- end customer routes -->
<!-- customer address routes --> <!-- customer address routes -->
@@ -152,10 +157,6 @@
</route> </route>
<!-- end order management process --> <!-- end order management process -->
<route id="mail.test" path="/mail/test">
<default key="_controller">Thelia\Controller\Front\Mail::test</default>
</route>
<!-- contact management --> <!-- contact management -->
<route id="contact.send" path="/contact" methods="post"> <route id="contact.send" path="/contact" methods="post">
<default key="_controller">Thelia\Controller\Front\ContactController::sendAction</default> <default key="_controller">Thelia\Controller\Front\ContactController::sendAction</default>

View File

@@ -202,48 +202,28 @@ class OrderController extends BaseAdminController
public function generateInvoicePdf($order_id) public function generateInvoicePdf($order_id)
{ {
return $this->generatePdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice')); if (null !== $response = $this->checkAuth(AdminResources::ORDER, AccessManager::UPDATE)) return $response;
return $this->generateBackOfficeOrderPdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice'));
} }
public function generateDeliveryPdf($order_id) public function generateDeliveryPdf($order_id)
{ {
return $this->generatePdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery')); if (null !== $response = $this->checkAuth(AdminResources::ORDER, AccessManager::UPDATE)) return $response;
return $this->generateBackOfficeOrderPdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery'));
} }
protected function generatePdf($order_id, $fileName) private function generateBackOfficeOrderPdf($order_id, $fileName)
{ {
if (null !== $response = $this->checkAuth(AdminResources::ORDER, array(), AccessManager::UPDATE)) return $response; if(null === $response = $this->generateOrderPdf($order_id, $fileName)){
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute("admin.order.update.view", array(
$html = $this->renderRaw(
$fileName,
array(
'order_id' => $order_id 'order_id' => $order_id
), ))));
TemplateHelper::getInstance()->getActivePdfTemplate()->getPath()
);
$order = OrderQuery::create()->findPk($order_id);
try {
$pdfEvent = new PdfEvent($html);
$this->dispatch(TheliaEvents::GENERATE_PDF, $pdfEvent);
if ($pdfEvent->hasPdf()) {
return Response::create($pdfEvent->getPdf(), 200,
array(
'Content-type' => "application/pdf",
'Content-Disposition' => sprintf('Attachment;filename=%s.pdf', $order->getRef()),
));
}
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf('error during generating invoice pdf for order id : %d with message "%s"', $order_id, $e->getMessage()));
} }
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute("admin.order.update.view", array( return $response;
'order_id' => $order_id
))));
} }
} }

View File

@@ -22,6 +22,8 @@
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\Controller; namespace Thelia\Controller;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Response; use Thelia\Core\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\DependencyInjection\ContainerAware;
@@ -31,7 +33,9 @@ use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Router; use Symfony\Component\Routing\Router;
use Thelia\Core\Security\SecurityContext; use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Core\Translation\Translator; use Thelia\Core\Translation\Translator;
use Thelia\Model\OrderQuery;
use Thelia\Tools\URL; use Thelia\Tools\URL;
use Thelia\Tools\Redirect; use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext; use Thelia\Core\Template\ParserContext;
@@ -52,7 +56,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @author Manuel Raynaud <mraynaud@openstudio.fr> * @author Manuel Raynaud <mraynaud@openstudio.fr>
*/ */
class BaseController extends ContainerAware abstract class BaseController extends ContainerAware
{ {
/** /**
@@ -73,6 +77,21 @@ class BaseController extends ContainerAware
return new Response($json_data, $status, array('content-type' => 'application/json')); return new Response($json_data, $status, array('content-type' => 'application/json'));
} }
/**
* @param $pdf
* @param $fileName
* @param $status
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function pdfResponse($pdf, $fileName, $status = 200)
{
return Response::create($pdf, $status,
array(
'Content-type' => "application/pdf",
'Content-Disposition' => sprintf('Attachment;filename=%s.pdf', $fileName),
));
}
/** /**
* Dispatch a Thelia event * Dispatch a Thelia event
* *
@@ -207,6 +226,35 @@ class BaseController extends ContainerAware
} }
} }
protected function generateOrderPdf($order_id, $fileName)
{
$html = $this->renderRaw(
$fileName,
array(
'order_id' => $order_id
),
TemplateHelper::getInstance()->getActivePdfTemplate()->getPath()
);
$order = OrderQuery::create()->findPk($order_id);
try {
$pdfEvent = new PdfEvent($html);
$this->dispatch(TheliaEvents::GENERATE_PDF, $pdfEvent);
if ($pdfEvent->hasPdf()) {
return $this->pdfResponse($pdfEvent->getPdf(), $order->getRef());
}
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf('error during generating invoice pdf for order id : %d with message "%s"', $order_id, $e->getMessage()));
}
}
/** /**
* *
* redirect request to the specified url * redirect request to the specified url
@@ -311,20 +359,28 @@ class BaseController extends ContainerAware
} }
/** /**
* * @return a ParserInterface instance parser
* return an instance of SmartyParser
*
* Caution : maybe there is still not default template defined.
*
* @return ParserInterface instance parser
*/ */
protected function getParser() abstract protected function getParser($template = null);
{
return $this->container->get("thelia.parser");
}
protected function render($inline) /**
{ * Render the given template, and returns the result as an Http Response.
return $this->getParser()->fetch(sprintf("string:%s", $inline)); *
} * @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param int $status http code status
* @return \Thelia\Core\HttpFoundation\Response
*/
abstract protected function render($templateName, $args = array(), $status = 200);
/**
* Render the given template, and returns the result as a string.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param null $templateDir
*
* @return string
*/
abstract protected function renderRaw($templateName, $args = array(), $templateDir = null);
} }

View File

@@ -24,9 +24,13 @@ namespace Thelia\Controller\Front;
use Symfony\Component\Routing\Router; use Symfony\Component\Routing\Router;
use Thelia\Controller\BaseController; use Thelia\Controller\BaseController;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Model\AddressQuery; use Thelia\Model\AddressQuery;
use Thelia\Model\ConfigQuery; use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery; use Thelia\Model\ModuleQuery;
use Thelia\Tools\Redirect;
use Thelia\Tools\URL; use Thelia\Tools\URL;
class BaseFrontController extends BaseController class BaseFrontController extends BaseController
@@ -88,12 +92,59 @@ class BaseFrontController extends BaseController
/** /**
* @return ParserInterface instance parser * @return ParserInterface instance parser
*/ */
protected function getParser() protected function getParser($template = null)
{ {
$parser = $this->container->get("thelia.parser"); $parser = $this->container->get("thelia.parser");
$parser->setTemplate(ConfigQuery::getActiveTemplate()); // Define the template that should be used
$parser->setTemplate($template ?: TemplateHelper::getInstance()->getActiveFrontTemplate()->getPath());
return $parser; return $parser;
} }
/**
* Render the given template, and returns the result as an Http Response.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param int $status http code status
* @return \Thelia\Core\HttpFoundation\Response
*/
protected function render($templateName, $args = array(), $status = 200)
{
return Response::create($this->renderRaw($templateName, $args), $status);
}
/**
* Render the given template, and returns the result as a string.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param null $templateDir
*
* @return string
*/
protected function renderRaw($templateName, $args = array(), $templateDir = null)
{
// Add the template standard extension
$templateName .= '.html';
$session = $this->getSession();
// Prepare common template variables
$args = array_merge($args, array(
'locale' => $session->getLang()->getLocale(),
'lang_code' => $session->getLang()->getCode(),
'lang_id' => $session->getLang()->getId(),
'current_url' => $this->getRequest()->getUri()
));
// Render the template.
$data = $this->getParser($templateDir)->render($templateName, $args);
return $data;
}
} }

View File

@@ -1,48 +0,0 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Front;
/**
* Class Mail
* @package Thelia\Controller\Front
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Mail extends BaseFrontController
{
/**
* This is a demo how to send a mail using swiftmailer + smarty
*/
public function test()
{
$message = \Swift_Message::newInstance('Wonderful Subject')
->setFrom(array('john@doe.com' => 'John Doe'))
->setTo(array('mraynaud@openstudio.fr' => 'name'))
->setBody($this->render('Here is the message itself'))
;
$this->getMailer()->send($message);
exit;
}
}

View File

@@ -23,6 +23,9 @@
namespace Thelia\Controller\Front; namespace Thelia\Controller\Front;
use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Exception\PropelException;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Exception\TheliaProcessException; use Thelia\Exception\TheliaProcessException;
use Thelia\Form\Exception\FormValidationException; use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\Order\OrderEvent; use Thelia\Core\Event\Order\OrderEvent;
@@ -34,6 +37,7 @@ use Thelia\Log\Tlog;
use Thelia\Model\AddressQuery; use Thelia\Model\AddressQuery;
use Thelia\Model\AreaDeliveryModuleQuery; use Thelia\Model\AreaDeliveryModuleQuery;
use Thelia\Model\Base\OrderQuery; use Thelia\Model\Base\OrderQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery; use Thelia\Model\ModuleQuery;
use Thelia\Model\Order; use Thelia\Model\Order;
use Thelia\Tools\URL; use Thelia\Tools\URL;
@@ -67,7 +71,6 @@ class OrderController extends BaseFrontController
$deliveryModule = ModuleQuery::create()->findPk($deliveryModuleId); $deliveryModule = ModuleQuery::create()->findPk($deliveryModuleId);
/* check that the delivery address belongs to the current customer */ /* check that the delivery address belongs to the current customer */
$deliveryAddress = AddressQuery::create()->findPk($deliveryAddressId);
if ($deliveryAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) { if ($deliveryAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) {
throw new \Exception("Delivery address does not belong to the current customer"); throw new \Exception("Delivery address does not belong to the current customer");
} }
@@ -242,4 +245,20 @@ class OrderController extends BaseFrontController
return $order; return $order;
} }
public function generateInvoicePdf($order_id)
{
/* check customer */
$this->checkAuth();
return $this->generateOrderPdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice'));
}
public function generateDeliveryPdf($order_id)
{
/* check customer */
$this->checkAuth();
return $this->generateOrderPdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery'));
}
} }

View File

@@ -33,6 +33,8 @@ use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\LangQuery; use Thelia\Model\LangQuery;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Type\TypeCollection;
use Thelia\Type;
/** /**
* Language loop, to get a list of available languages * Language loop, to get a list of available languages
@@ -56,7 +58,14 @@ class Lang extends BaseLoop implements PropelSearchLoopInterface
return new ArgumentCollection( return new ArgumentCollection(
Argument::createIntTypeArgument('id', null), Argument::createIntTypeArgument('id', null),
Argument::createIntListTypeArgument('exclude'), Argument::createIntListTypeArgument('exclude'),
Argument::createBooleanTypeArgument('default_only', false) Argument::createBooleanTypeArgument('default_only', false),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'position', 'position_reverse'))
),
'position'
)
); );
} }
@@ -79,6 +88,30 @@ class Lang extends BaseLoop implements PropelSearchLoopInterface
} }
$search->orderByPosition(Criteria::ASC); $search->orderByPosition(Criteria::ASC);
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->orderByTitle(Criteria::ASC);
break;
case "alpha_reverse":
$search->orderByTitle(Criteria::DESC);
break;
case "position":
$search->orderByPosition(Criteria::ASC);
break;
case "position_reverse":
$search->orderByPosition(Criteria::DESC);
break;
}
}
return $search; return $search;

View File

@@ -25,7 +25,7 @@
<h1 id="main-label" class="page-header">{intl l="Change Password"}</h1> <h1 id="main-label" class="page-header">{intl l="Change Password"}</h1>
{form name="thelia.front.customer.password.update"} {form name="thelia.front.customer.password.update"}
<form id="form-register" class="form-horizontal" action="{url path="/account/password"}" method="post" role="form"> <form id="form-register" class="form-horizontal" action="{url path="/account/password"}" method="post">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> <input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field} {/form_field}

View File

@@ -24,7 +24,7 @@
<h1 id="main-label" class="page-header">{intl l="Update Profile"}</h1> <h1 id="main-label" class="page-header">{intl l="Update Profile"}</h1>
{form name="thelia.front.customer.profile.update"} {form name="thelia.front.customer.profile.update"}
<form id="form-register" class="form-horizontal" action="{url path="/account/update"}" method="post" role="form"> <form id="form-register" class="form-horizontal" action="{url path="/account/update"}" method="post">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> <input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field} {/form_field}

View File

@@ -158,7 +158,7 @@
<td>{format_date date=$CREATE_DATE}</td> <td>{format_date date=$CREATE_DATE}</td>
<td>{format_number number=$TOTAL_TAXED_AMOUNT} {loop type="currency" name="order.currency" id={$CURRENCY}}{$SYMBOL}{/loop}</td> <td>{format_number number=$TOTAL_TAXED_AMOUNT} {loop type="currency" name="order.currency" id={$CURRENCY}}{$SYMBOL}{/loop}</td>
<td><span class="label-delivered">{loop type="order-status" name="order.status" id={$STATUS}}{$TITLE}{/loop}</span></td> <td><span class="label-delivered">{loop type="order-status" name="order.status" id={$STATUS}}{$TITLE}{/loop}</span></td>
<td><a href="#" class="btn btn-order-details" data-toggle="tooltip" title="{intl l="View order %ref as pdf document" ref={$REF}}"><span class="icon-cloud-download"></span> {intl l="Order details"}</a></td> <td><a href="{url path="/account/order/pdf/delivery/$ID"}" class="btn btn-order-details" data-toggle="tooltip" title="{intl l="View order %ref as pdf document" ref={$REF}}"><span class="icon-cloud-download"></span> {intl l="Order details"}</a></td>
</tr> </tr>
{/loop} {/loop}

View File

@@ -24,7 +24,7 @@
<h1 id="main-label" class="page-header">{intl l="Address Update"}</h1> <h1 id="main-label" class="page-header">{intl l="Address Update"}</h1>
{form name="thelia.front.address.update"} {form name="thelia.front.address.update"}
{loop name="customer.update" type="address" customer="current" id="{$address_id}"} {loop name="customer.update" type="address" customer="current" id="{$address_id}"}
<form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post" role="form"> <form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> <input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field} {/form_field}

View File

@@ -23,7 +23,7 @@
<h1 id="main-label" class="page-header">{intl l="Create New Address"}</h1> <h1 id="main-label" class="page-header">{intl l="Create New Address"}</h1>
{form name="thelia.front.address.create"} {form name="thelia.front.address.create"}
<form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post" role="form"> <form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> <input type="hidden" name="{$name}" value="{url path="/account"}" />
{/form_field} {/form_field}

View File

@@ -1,22 +1,23 @@
/* JQUERY PREVENT CONFLICT */ /* JQUERY PREVENT CONFLICT */
(function($) { (function ($) {
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
callback Function -------------------------------------------------- */ callback Function -------------------------------------------------- */
var confirmCallback = { var confirmCallback = {
'address.delete': function($elm){ 'address.delete': function ($elm) {
$.post($elm.attr('href'), function(data){ $.post($elm.attr('href'), function (data) {
if(data.success) if (data.success) {
$elm.closest('tr').remove(); $elm.closest('tr').remove();
else } else {
bootbox.alert(data.message); bootbox.alert(data.message);
}
}); });
} }
} };
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
onLoad Function -------------------------------------------------- */ onLoad Function -------------------------------------------------- */
$(document).ready(function(){ $(document).ready(function () {
// Loader // Loader
var $loader = $('<div class="loader"></div>'); var $loader = $('<div class="loader"></div>');
@@ -24,32 +25,29 @@
// Display loader if we do ajax call // Display loader if we do ajax call
$(document) $(document)
.ajaxStart(function() { $loader.show(); }) .ajaxStart(function () { $loader.show(); })
.ajaxStop(function(){ $loader.hide(); }); .ajaxStop(function () { $loader.hide(); });
// Main Navigation Hover // Main Navigation Hover
$('.nav-main') $('.nav-main')
.on('click.subnav', '[data-toggle=dropdown]', function(event){ .on('click.subnav', '[data-toggle=dropdown]', function (event) {
if($(this).parent().hasClass('open') && $(this).is(event.target)) if ($(this).parent().hasClass('open') && $(this).is(event.target)) { return false; }
return false;
}) })
.on('mouseenter.subnav', '.dropdown', function(event){ .on('mouseenter.subnav', '.dropdown', function () {
if($(this).hasClass('open')) if ($(this).hasClass('open')) { return; }
return;
$(this).addClass('open'); $(this).addClass('open');
}) })
.on('mouseleave.subnav', '.dropdown', function(){ .on('mouseleave.subnav', '.dropdown', function () {
var $this = $(this); var $this = $(this);
if(!$this.hasClass('open')) if (!$this.hasClass('open')) { return; }
return;
//This will check if an input child has focus. If no then remove class open //This will check if an input child has focus. If no then remove class open
if ($this.find(":input:focus").length == 0){ if ($this.find(":input:focus").length === 0) {
$this.removeClass('open'); $this.removeClass('open');
} else { } else {
$this.find(":input:focus").one('blur', function(){ $this.find(":input:focus").one('blur', function () {
$this.trigger('mouseleave.subnav'); $this.trigger('mouseleave.subnav');
}); });
} }
@@ -61,56 +59,55 @@
}); });
// Confirm Dialog // Confirm Dialog
$(document).on('click.confirm', '[data-confirm]', function (e) { $(document).on('click.confirm', '[data-confirm]', function () {
var $this = $(this), var $this = $(this),
href = $this.attr('href'), href = $this.attr('href'),
callback = $this.attr('data-confirm-callback'), callback = $this.attr('data-confirm-callback'),
title = $this.attr('data-confirm') != '' ? $this.attr('data-confirm') : 'Are you sure?'; title = $this.attr('data-confirm') !== '' ? $this.attr('data-confirm') : 'Are you sure?';
bootbox.confirm(title, function(confirm) { bootbox.confirm(title, function (confirm) {
if(confirm){ if (confirm) {
//Check if callback and if it's a function //Check if callback and if it's a function
if (callback && $.isFunction(confirmCallback[callback])) { if (callback && $.isFunction(confirmCallback[callback])) {
confirmCallback[callback]($this); confirmCallback[callback]($this);
} else {
if (href) {
window.location.href = href;
} else { } else {
if(href){ // If forms
window.location.href = href; var $form = $this.closest("form");
} else { if ($form.size() > 0) {
// If forms $form.submit();
var $form = $this.closest("form");
if($form.size() > 0){
$form.submit();
}
} }
} }
} }
}); }
});
return false; return false;
}); });
// Toolbar // Toolbar
var $category_products = $('#category-products'); var $category_products = $ ('#category-products');
if($category_products.size() > 0){ if ($category_products.size() > 0) {
var $parent = $category_products.parent(); var $parent = $category_products.parent();
$parent.on('click.view-mode', '[data-toggle=view]', function(){ $parent.on('click.view-mode', '[data-toggle=view]', function () {
if( ($(this).hasClass('btn-grid') && $parent.hasClass('grid')) || ($(this).hasClass('btn-list') && $parent.hasClass('list'))) if (($(this).hasClass('btn-grid') && $parent.hasClass('grid')) || ($(this).hasClass('btn-list') && $parent.hasClass('list'))) { return; }
return;
// Add loader effect // Add loader effect
$loader.show(); $loader.show();
setTimeout(function(){ $parent.toggleClass('grid').toggleClass('list'); $loader.hide(); }, 400); setTimeout(function () { $parent.toggleClass('grid').toggleClass('list'); $loader.hide(); }, 400);
return false; return false;
}); });
} };
// Login // Login
var $form_login = $('#form-login'); var $form_login = $('#form-login');
if($form_login.size() > 0) { if ($form_login.size() > 0) {
$form_login.on('change.account', ':radio', function(){ $form_login.on('change.account', ':radio', function () {
if($(this).val() === '0') if ($(this).val() === '0')
$('#password', $form_login).val('').prop('disabled', true); // Disabled (new customer) $('#password', $form_login).val('').prop('disabled', true); // Disabled (new customer)
else else
$('#password', $form_login).prop('disabled', false); // Enabled $('#password', $form_login).prop('disabled', false); // Enabled
@@ -119,19 +116,19 @@
// Mini Newsletter Subscription // Mini Newsletter Subscription
var $form_newsletter = $('#form-newsletter-mini'); var $form_newsletter = $('#form-newsletter-mini');
if($form_newsletter.size() > 0) { if ($form_newsletter.size() > 0) {
$form_newsletter.on('submit.newsletter', function(){ $form_newsletter.on('submit.newsletter', function () {
$.ajax({ $.ajax({
url: $(this).attr('action'), url: $(this).attr('action'),
type: $(this).attr('method'), type: $(this).attr('method'),
data: $(this).serialize(), data: $(this).serialize(),
dataType: 'json', dataType: 'json',
success: function(json) { success: function (json) {
var $msg = ''; var $msg = '';
if(json.success){ if (json.success) {
$msg = json.message; $msg = json.message;
}else{ } else {
$msg = json.message; $msg = json.message;
} }
bootbox.alert($msg); bootbox.alert($msg);
@@ -153,14 +150,14 @@
content: function() { content: function() {
return $('#form-forgotpassword').html(); return $('#form-forgotpassword').html();
} }
}).on('click.btn-forgot', function(){ }).on('click.btn-forgot', function () {
$('.btn-forgot').click(function(){ $('.btn-forgot').click(function () {
alert('click form'); alert('click form');
return false; return false;
}); });
$('.btn-close').click(function(){ $('.btn-close').click(function () {
$forgot_password.popover('hide'); $forgot_password.popover('hide');
}); });
@@ -170,11 +167,11 @@
*/ */
//.Form Filters //.Form Filters
$('#form-filters').each(function(){ $('#form-filters').each(function () {
var $form = $(this); var $form = $(this);
$form $form
.on('change.filter', ':checkbox', function(){ .on('change.filter', ':checkbox', function () {
$loader.show(); $loader.show();
$form.submit(); $form.submit();
}) })
@@ -182,19 +179,18 @@
}); });
// Product details Thumbnails // Product details Thumbnails
$('#product-gallery').each(function(){ $('#product-gallery').each(function () {
var $item = $('.item', this), var $item = $('.item', this),
$thumbnails = $('.thumbnail', this), $thumbnails = $('.thumbnail', this),
$image = $('.product-image > img', this); $image = $('.product-image > img', this);
// Show Carousel control if needed // Show Carousel control if needed
if($item.size() > 1){ if ($item.size() > 1) {
$('#product-thumbnails', this).carousel({interval: false}).find('.carousel-control').show(); $('#product-thumbnails', this).carousel({interval: false}).find('.carousel-control').show();
} }
$(this).on('click.thumbnails', '.thumbnail', function(){ $(this).on('click.thumbnails', '.thumbnail', function () {
if($(this).hasClass('active')) if ($(this).hasClass('active')) { return false; }
return false;
$image.attr('src',$(this).attr('href')); $image.attr('src',$(this).attr('href'));
$thumbnails.removeClass('active'); $thumbnails.removeClass('active');
@@ -205,9 +201,9 @@
}); });
// Payment Method // Payment Method
$('#payment-method').each(function(){ $('#payment-method').each(function () {
var $label = $('label', this); var $label = $('label', this);
$label.on('change', ':radio', function(){ $label.on('change', ':radio', function () {
$label.removeClass('active'); $label.removeClass('active');
$label.filter('[for="' + $(this).attr('id') + '"]').addClass('active'); $label.filter('[for="' + $(this).attr('id') + '"]').addClass('active');
}).filter(':has(:checked)').addClass('active'); }).filter(':has(:checked)').addClass('active');
@@ -215,21 +211,14 @@
// Apply validation // Apply validation
$('#form-contact, #form-register, #form-address').validate({ $('#form-contact, #form-register, #form-address').validate({
highlight: function(element) { highlight: function (element) {
$(element).closest('.form-group').addClass('has-error'); $(element).closest('.form-group').addClass('has-error');
}, },
unhighlight: function(element) { unhighlight: function (element) {
$(element).closest('.form-group').removeClass('has-error'); $(element).closest('.form-group').removeClass('has-error');
}, },
errorElement: 'span', errorElement: 'span',
errorClass: 'help-block'/*, errorClass: 'help-block'
errorPlacement: function(error, element) {
if(element.parent('.input-group').length || element.prop('type') === 'checkbox' || element.prop('type') === 'radio'){
error.prepend('<i class="icon-remove"></i> ').insertAfter(element.parent());
}else{
error.prepend('<i class="icon-remove"></i> ').insertAfter(element);
}
}*/
}); });
@@ -253,14 +242,14 @@
// Switch Quantity in product page // Switch Quantity in product page
$("select", $(".product-options")).change(function(){ $("select", $(".product-options")).change(function(){
$select_quantity = $(this).find(":selected").attr("data-quantity"); $select_quantity = $(this).find(":selected").attr("data-quantity");
var $old_price = $(this).find(":selected").attr("data-old-price"); var $old_price = $(this).find(":selected").attr("data-old-price");
var $best_price = $(this).find(":selected").attr("data-price"); var $best_price = $(this).find(":selected").attr("data-price");
$quantityInput.attr("max", $select_quantity); $quantityInput.attr("max", $select_quantity);
// Show Out Of Stock OR In Stock // Show Out Of Stock OR In Stock
if($select_quantity == 0){ if ($select_quantity == 0) {
$btnAddToCart.attr("disabled", true); $btnAddToCart.attr("disabled", true);
$productMeta.removeClass("in-stock"); $productMeta.removeClass("in-stock");
@@ -271,7 +260,7 @@
$outOfStock.show(); $outOfStock.show();
$inStock.hide(); $inStock.hide();
}else{ } else {
$btnAddToCart.attr("disabled", false); $btnAddToCart.attr("disabled", false);
$productMeta.removeClass("out-of-stock"); $productMeta.removeClass("out-of-stock");
@@ -283,38 +272,38 @@
$outOfStock.hide(); $outOfStock.hide();
} }
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){ if (parseInt($quantityInput.val()) > parseInt($select_quantity)) {
$quantityInput.val($select_quantity); $quantityInput.val($select_quantity);
} }
if($old_price_container.size() > 0 ){ if ($old_price_container.size() > 0) {
$(".price", $old_price_container).html($old_price); $(".price", $old_price_container).html($old_price);
$(".price", $(".special-price")).html($best_price); $(".price", $(".special-price")).html($best_price);
}else{ } else {
$(".price", $(".regular-price")).html($best_price); $(".price", $(".regular-price")).html($best_price);
} }
}).change(); }).change();
$quantityInput.focusout(function() { $quantityInput.focusout(function () {
$quantityInput.attr("max", $select_quantity); $quantityInput.attr("max", $select_quantity);
if(parseInt($quantityInput.val()) > parseInt($select_quantity)){ if (parseInt($quantityInput.val()) > parseInt($select_quantity)) {
$quantityInput.val($select_quantity); $quantityInput.val($select_quantity);
} }
}); });
} }
$(".form-product").submit(function(){ $(".form-product").submit(function () {
var url_action = $(this).attr("action"); var url_action = $(this).attr("action");
var $cartContainer = $(".cart-container"); var $cartContainer = $(".cart-container");
$.ajax({type:"POST", data: $(this).serialize(), url:url_action, $.ajax({type: "POST", data: $(this).serialize(), url: url_action,
success: function(data){ success: function(data){
$cartContainer.html($(data).html()); $cartContainer.html($(data).html());
$.ajax({url:"ajax/addCartMessage", $.ajax({url:"ajax/addCartMessage",
success: function(data){ success: function (data) {
bootbox.dialog({ bootbox.dialog({
message : data, message : data,
buttons : {} buttons : {}
@@ -322,7 +311,7 @@
} }
}); });
}, },
error: function(){ error: function () {
console.log('Error.'); console.log('Error.');
} }
}); });
@@ -330,11 +319,11 @@
return false; return false;
}); });
$('#limit-top').change(function(e){ $('#limit-top').change(function (e) {
window.location = $(this).val() window.location = $(this).val()
}); });
$('#sortby-top').change(function(e){ $('#sortby-top').change(function (e) {
window.location = $(this).val() window.location = $(this).val()
}); });

View File

@@ -6,6 +6,9 @@
// Collapse // Collapse
.no-js .collapse { display: block!important; } .no-js .collapse { display: block!important; }
// Hide carousel arrow if no js
.no-js #carousel .carousel-control { display: none; }
// Loader (Overlay) // Loader (Overlay)
.loader { .loader {
position: fixed; position: fixed;

View File

@@ -78,7 +78,7 @@
// Icons (Accordion and Dropdown) // Icons (Accordion and Dropdown)
//.accordion-toggle, //.accordion-toggle,
.dropdown-toggle { .js .dropdown-toggle {
&:after { &:after {
.icon(@chevron-down); .icon(@chevron-down);
float:right; float:right;

View File

@@ -98,7 +98,7 @@
</td> </td>
<td class="qty"> <td class="qty">
<div class="form-group group-qty"> <div class="form-group group-qty">
<form action="{url path="/cart/update"}" method="post" role="form"> <form action="{url path="/cart/update"}" method="post">
<input type="hidden" name="cart_item" value="{$ITEM_ID}"> <input type="hidden" name="cart_item" value="{$ITEM_ID}">
<select name="quantity" class="form-control" onchange="jQuery(this).parent('form').submit();"> <select name="quantity" class="form-control" onchange="jQuery(this).parent('form').submit();">
{for $will=1 to $STOCK} {for $will=1 to $STOCK}

View File

@@ -16,7 +16,7 @@
{block name="contact-form"} {block name="contact-form"}
{form name="thelia.front.contact"} {form name="thelia.front.contact"}
<form id="form-contact" action="{url path="/contact"}" method="post" role="form"> <form id="form-contact" action="{url path="/contact"}" method="post">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
<fieldset id="contact-info" class="panel"> <fieldset id="contact-info" class="panel">
<div class="panel-heading"> <div class="panel-heading">

View File

@@ -0,0 +1,25 @@
{extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-currency{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Currency"}, 'url'=>{url path="/currency"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="SELECT YOUR CURRENCY"}</h1>
<ul class="nav nav-tabs nav-justified" style="margin-bottom:60px;">
{loop type="currency" name="currency_available"}
<li{if $ID eq "{currency attr="id"}"} class="active"{/if}><a href="{url path="{navigate to="current"}" currency={$ISOCODE}}">{$SYMBOL} - {$NAME}</a></li>
{/loop}
</ul>
</article>
</div>
{/block}

View File

@@ -1,6 +1,6 @@
<section id="filters"> <section id="filters">
<h3>Find <span>a product</span></h3> <h3>Find <span>a product</span></h3>
<form id="form-filters" action="" method="get" role="form"> <form id="form-filters" action="" method="get">
<div class="filter filter-type"> <div class="filter filter-type">
<fieldset> <fieldset>
<legend class="filter-heading">Type</legend> <legend class="filter-heading">Type</legend>

View File

@@ -4,7 +4,7 @@
{intl l="Cart"} <span class="badge">{cart attr="count_item"}</span> {intl l="Cart"} <span class="badge">{cart attr="count_item"}</span>
</a> </a>
<div class="dropdown-menu cart-content"> <div class="dropdown-menu cart-content">
<form id="form-cart-mini" action="{url path="/order/delivery"}" method="post" role="form"> <form id="form-cart-mini" action="{url path="/order/delivery"}" method="post">
<table class="table table-cart-mini"> <table class="table table-cart-mini">
<colgroup> <colgroup>
<col width="70"> <col width="70">

View File

@@ -60,7 +60,7 @@
</div> </div>
{if $hasBtn == true} {if $hasBtn == true}
{form name="thelia.cart.add" } {form name="thelia.cart.add" }
<form id="form-product-details" action="{url path="/cart/add" }" method="post" role="form" class="form-product"> <form id="form-product-details" action="{url path="/cart/add" }" method="post" class="form-product">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
<input type="hidden" name="view" value="product"> <input type="hidden" name="view" value="product">
<input type="hidden" name="product_id" value="{$ID}"> <input type="hidden" name="product_id" value="{$ID}">

View File

@@ -0,0 +1,25 @@
{extends file="layout.tpl"}
{* Body Class *}
{block name="body-class"}page-language{/block}
{* Breadcrumb *}
{block name='no-return-functions' append}
{$breadcrumbs = [
['title' => {intl l="Language"}, 'url'=>{url path="/language"}]
]}
{/block}
{block name="main-content"}
<div class="main">
<article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="SELECT YOUR LANGUAGE"}</h1>
<ul class="nav nav-tabs nav-justified" style="margin-bottom:60px;">
{loop type="lang" name="lang_available"}
<li{if $ID eq "{lang attr="id"}"} class="active"{/if}><a href="{url path="{navigate to="current"}" lang={$CODE}}">{$TITLE}</a></li>
{/loop}
</ul>
</article>
</div>
{/block}

View File

@@ -1,6 +1,10 @@
{* Declare assets directory, relative to template base directory *} {* Declare assets directory, relative to template base directory *}
{declare_assets directory='assets'} {declare_assets directory='assets'}
{block name="no-return-functions"}{/block} {block name="no-return-functions"}{/block}
{assign var="company_name" value="{config key="company_name"}"}
{if not $company_name}
{assign var="company_name" value="{intl l='Thelia V2'}"}
{/if}
<!doctype html> <!doctype html>
<!-- <!--
______ __ __ ______ __ __ ______ ______ __ __ ______ __ __ ______
@@ -33,15 +37,16 @@ GNU General Public License : http://www.gnu.org/licenses/
<meta charset="utf-8"> <meta charset="utf-8">
{* Page Title *} {* Page Title *}
<title>{block name="page-title"}{strip}{if $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title} - {/foreach}{/if}{config key="company_name"}{/strip}{/block}</title> <title>{block name="page-title"}{strip}{if $breadcrumbs}{foreach from=$breadcrumbs|array_reverse item=breadcrumb}{$breadcrumb.title} - {/foreach}{/if}{$company_name}{/strip}{/block}</title>
{* Meta Tags *} {* Meta Tags *}
<meta name="description" content="">
<meta name="generator" content="{intl l='Thelia V2'}"> <meta name="generator" content="{intl l='Thelia V2'}">
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
{block name="meta"}{/block} {block name="meta"}
<meta name="description" content="{$company_name}">
<meta name="robots" content="noindex,nofollow">
{/block}
{* Stylesheets *} {* Stylesheets *}
{stylesheets file='assets/less/styles.less' filters='less'} {stylesheets file='assets/less/styles.less' filters='less'}
@@ -54,14 +59,10 @@ GNU General Public License : http://www.gnu.org/licenses/
{images file='assets/img/favicon.ico'}<link rel="shortcut icon" type="image/x-icon" href="{$asset_url}">{/images} {images file='assets/img/favicon.ico'}<link rel="shortcut icon" type="image/x-icon" href="{$asset_url}">{/images}
{images file='assets/img/favicon.png'}<link rel="icon" type="image/png" href="{$asset_url}" />{/images} {images file='assets/img/favicon.png'}<link rel="icon" type="image/png" href="{$asset_url}" />{/images}
<link rel="icon" href="/favicon.ico" type="image/x-icon">
{* HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries *} {* HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries *}
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
{javascripts file='assets/js/libs/respond.min.js'} <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<script src="{$asset_url}"></script>
{/javascripts}
<![endif]--> <![endif]-->
</head> </head>
@@ -85,7 +86,7 @@ GNU General Public License : http://www.gnu.org/licenses/
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{navigate to="index"}">{config key="company_name"}</a> <a class="navbar-brand" href="{navigate to="index"}">{$company_name}</a>
</div> </div>
<!-- Place everything within .nav-collapse to hide it until above 768px --> <!-- Place everything within .nav-collapse to hide it until above 768px -->
@@ -102,18 +103,18 @@ GNU General Public License : http://www.gnu.org/licenses/
<a href="{url path="/login"}" class="login">{intl l="Log In!"}</a> <a href="{url path="/login"}" class="login">{intl l="Log In!"}</a>
<div class="dropdown-menu"> <div class="dropdown-menu">
{form name="thelia.front.customer.login"} {form name="thelia.front.customer.login"}
<form id="form-login-mini" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form}> <form id="form-login-mini" action="{url path="/login"}" method="post" {form_enctype form=$form}>
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field="email"} {form_field form=$form field="email"}
<div class="form-group group-email"> <div class="form-group group-email">
<label for="{$label_attr.for}-mini">Email address</label> <label for="{$label_attr.for}-mini">{intl l="Email address"}</label>
<input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required> <input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" maxlength="255" aria-required="true" required>
</div> </div>
{/form_field} {/form_field}
{form_field form=$form field="password"} {form_field form=$form field="password"}
<div class="form-group group-password"> <div class="form-group group-password">
<label for="{$label_attr.for}-mini">Password</label> <label for="{$label_attr.for}-mini">{intl l="Password"}</label>
<input type="password" name="{$name}" id="{$label_attr.for}-mini" class="form-control" aria-required="true" required> <input type="password" name="{$name}" id="{$label_attr.for}-mini" class="form-control" maxlength="255" aria-required="true" required>
</div> </div>
{/form_field} {/form_field}
{form_field form=$form field="account"} {form_field form=$form field="account"}
@@ -145,8 +146,8 @@ GNU General Public License : http://www.gnu.org/licenses/
<header class="container" role="banner"> <header class="container" role="banner">
<div class="header"> <div class="header">
<h1 class="logo"> <h1 class="logo">
<a href="{navigate to="index"}" title="{config key="company_name"}"> <a href="{navigate to="index"}" title="{$company_name}">
{images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="{config key="company_name"}">{/images} {images file='assets/img/logo.gif'}<img src="{$asset_url}" alt="{$company_name}">{/images}
</a> </a>
</h1> </h1>
@@ -164,7 +165,7 @@ GNU General Public License : http://www.gnu.org/licenses/
</form> </form>
</div> </div>
<div class="language-switch" aria-labelledby="language-label"> <div class="language-switch" aria-labelledby="language-label" role="form">
<span id="language-label" class="dropdown-label">{intl l="Language:"}</span> <span id="language-label" class="dropdown-label">{intl l="Language:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/language"}">{lang attr="title"}</a> <a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/language"}">{lang attr="title"}</a>
<ul class="select dropdown-menu"> <ul class="select dropdown-menu">
@@ -174,7 +175,7 @@ GNU General Public License : http://www.gnu.org/licenses/
</ul> </ul>
</div> </div>
<div class="currency-switch" aria-labelledby="currency-label"> <div class="currency-switch" aria-labelledby="currency-label" role="form">
<span id="currency-label" class="dropdown-label">{intl l="Currency:"}</span> <span id="currency-label" class="dropdown-label">{intl l="Currency:"}</span>
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/currency"}">{currency attr="code"}</a> <a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/currency"}">{currency attr="code"}</a>
<ul class="select dropdown-menu"> <ul class="select dropdown-menu">
@@ -193,7 +194,7 @@ GNU General Public License : http://www.gnu.org/licenses/
<main class="main-container" role="main"> <main class="main-container" role="main">
<div class="container"> <div class="container">
{block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block} {block name="breadcrumb"}{include file="misc/breadcrumb.tpl"}{/block}
{block name="main-content"}{/block} <div id="content">{block name="main-content"}{/block}</div>
</div><!-- /.container --> </div><!-- /.container -->
</main><!-- /.main-container --> </main><!-- /.main-container -->
@@ -271,54 +272,60 @@ GNU General Public License : http://www.gnu.org/licenses/
<section class="block block-social"> <section class="block block-social">
<div class="block-heading"><h3 class="block-title">{intl l="Follow us"}</h3></div> <div class="block-heading"><h3 class="block-title">{intl l="Follow us"}</h3></div>
<div class="block-content"> <div class="block-content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> <p>{intl l="Follow us introduction"}</p>
<ul role="presentation"> <ul role="presentation">
<li> <li>
<a href="http://facebook.com" class="facebook" data-toggle="tooltip" data-placement="top" title="facebook" target="_blank"> <a href="http://facebook.com" rel="nofollow" class="facebook" data-toggle="tooltip" data-placement="top" title="{intl l="Facebook"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-facebook icon-light"></span> <span class="icon-facebook icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="Facebook"}</span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://twitter.com" class="twitter" data-toggle="tooltip" data-placement="top" title="twitter" target="_blank"> <a href="https://twitter.com" rel="nofollow" class="twitter" data-toggle="tooltip" data-placement="top" title="{intl l="Twitter"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-twitter icon-light"></span> <span class="icon-twitter icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="Twitter"}</span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://instagram.com" class="instagram" data-toggle="tooltip" data-placement="top" title="instagram" target="_blank"> <a href="http://instagram.com" rel="nofollow" class="instagram" data-toggle="tooltip" data-placement="top" title="{intl l="Instagram"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-instagram icon-light"></span> <span class="icon-instagram icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="Instagram"}</span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://google.com" class="google-plus" data-toggle="tooltip" data-placement="top" title="google+" target="_blank"> <a href="http://www.google.com" rel="nofollow" class="google-plus" data-toggle="tooltip" data-placement="top" title="{intl l="Google+"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-google-plus icon-light"></span> <span class="icon-google-plus icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="Google+"}</span>
</a> </a>
</li> </li>
<li> <li>
<a href="http://youtube.com" class="youtube" data-toggle="tooltip" data-placement="top" title="youtube" target="_blank"> <a href="http://www.youtube.com" rel="nofollow" class="youtube" data-toggle="tooltip" data-placement="top" title="{intl l="Youtube"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-youtube icon-light"></span> <span class="icon-youtube icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="Youtube"}</span>
</a> </a>
</li> </li>
<li> <li>
<a href="#rss" class="rss" data-toggle="tooltip" data-placement="top" title="rss" target="_blank"> <a href="#rss" class="rss" rel="nofollow" data-toggle="tooltip" data-placement="top" title="{intl l="RSS"}" target="_blank">
<span class="icon-stack"> <span class="icon-stack">
<span class="icon-circle icon-stack-base"></span> <span class="icon-circle icon-stack-base"></span>
<span class="icon-rss icon-light"></span> <span class="icon-rss icon-light"></span>
</span> </span>
<span class="visible-print">{intl l="RSS"}</span>
</a> </a>
</li> </li>
</ul> </ul>
@@ -328,14 +335,14 @@ GNU General Public License : http://www.gnu.org/licenses/
<section class="block block-newsletter"> <section class="block block-newsletter">
<div class="block-heading"><h3 class="block-title">{intl l="Newsletter"}</h3></div> <div class="block-heading"><h3 class="block-title">{intl l="Newsletter"}</h3></div>
<div class="block-content"> <div class="block-content">
<p id="newletter-describe">{intl l="Sign up to receive our latest news."}</p> <p id="newsletter-describe">{intl l="Sign up to receive our latest news."}</p>
{form name="thelia.front.newsletter"} {form name="thelia.front.newsletter"}
<form id="form-newsletter-mini" action="{url path="/newsletter"}" method="post" role="form"> <form id="form-newsletter-mini" action="{url path="/newsletter"}" method="post">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
{form_field form=$form field="email"} {form_field form=$form field="email"}
<div class="form-group"> <div class="form-group">
<label for="{$label_attr.for}-mini">{intl l="Email address"}</label> <label for="{$label_attr.for}-mini">{intl l="Email address"}</label>
<input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" placeholder="{intl l="Your email address"}" aria-describedby="newletter-describe" {if $required} aria-required="true" required{/if} autocomplete="off"> <input type="email" name="{$name}" id="{$label_attr.for}-mini" class="form-control" maxlength="255" placeholder="{intl l="Your email address"}" aria-describedby="newsletter-describe" {if $required} aria-required="true" required{/if} autocomplete="off">
</div> </div>
{/form_field} {/form_field}
<button type="submit" class="btn btn-subscribe">{intl l="Subscribe"}</button> <button type="submit" class="btn btn-subscribe">{intl l="Subscribe"}</button>
@@ -349,7 +356,7 @@ GNU General Public License : http://www.gnu.org/licenses/
<section class="block block-contact" itemscope itemtype="http://schema.org/Organization"> <section class="block block-contact" itemscope itemtype="http://schema.org/Organization">
<div class="block-heading"><h3 class="block-title">{intl l="Contact Us"}</h3></div> <div class="block-heading"><h3 class="block-title">{intl l="Contact Us"}</h3></div>
<div class="block-content"> <div class="block-content">
<meta itemprop="name" content="{config key="company_name"}"> <meta itemprop="name" content="{$company_name}">
<ul> <ul>
<li class="contact-address"> <li class="contact-address">
<address class="adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress"> <address class="adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
@@ -387,7 +394,7 @@ GNU General Public License : http://www.gnu.org/licenses/
</ul> </ul>
</nav> </nav>
<section class="copyright">{intl l="Copyright"} &copy; <time datetime="{'Y-m-d'|date}">{'Y'|date}</time> <a href="http://www.thelia.net" rel="external">Thelia</a></section> <section class="copyright">{intl l="Copyright"} &copy; <time datetime="{'Y-m-d'|date}">{'Y'|date}</time> <a href="http://thelia.net" rel="external">Thelia</a></section>
</div> </div>
</div> </div>
</footer><!-- /.footer-info --> </footer><!-- /.footer-info -->

View File

@@ -16,7 +16,7 @@
<article class="col-main" role="main" aria-labelledby="main-label"> <article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Login"}</h1> <h1 id="main-label" class="page-header">{intl l="Login"}</h1>
{form name="thelia.front.customer.login"} {form name="thelia.front.customer.login"}
<form id="form-login" action="{url path="/login"}" method="post" role="form" {form_enctype form=$form} novalidate> <form id="form-login" action="{url path="/login"}" method="post" {form_enctype form=$form} novalidate>
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if} {if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}"> {* the url the user is redirected to on login success *} <input type="hidden" name="{$name}" value="{navigate to="return_to"}"> {* the url the user is redirected to on login success *}

View File

@@ -11,7 +11,7 @@
<h1 id="main-label" class="page-header">{intl l="Newsletter Subscription"}</h1> <h1 id="main-label" class="page-header">{intl l="Newsletter Subscription"}</h1>
{form name="thelia.front.newsletter"} {form name="thelia.front.newsletter"}
<form id="form-newsletter" action="{url path="/newsletter"}" method="post" role="form"> <form id="form-newsletter" action="{url path="/newsletter"}" method="post">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
<p>{intl l="You want to subscribe to the newsletter? Please enter your email address below."}</p> <p>{intl l="You want to subscribe to the newsletter? Please enter your email address below."}</p>
{form_field form=$form field="email"} {form_field form=$form field="email"}
@@ -20,7 +20,7 @@
<div class="control-input"> <div class="control-input">
<input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" maxlength="255" {if $required} aria-required="true" required{/if} autofocus> <input type="email" name="{$name}" id="{$label_attr.for}" value="{$value}" class="form-control" maxlength="255" {if $required} aria-required="true" required{/if} autofocus>
{if $error} {if $error}
<span class="help-block"><span class="icon-remove"></span> {$message}</span> <span class="help-block">{$message}</span>
{elseif !$error && $value != ""} {elseif !$error && $value != ""}
<span class="help-block"><span class="icon-ok"></span> {intl l="Thanks for signing up! We'll keep you posted whenever we have any new updates."}</span> <span class="help-block"><span class="icon-ok"></span> {intl l="Thanks for signing up! We'll keep you posted whenever we have any new updates."}</span>
{/if} {/if}

View File

@@ -28,7 +28,7 @@
{form name="thelia.order.delivery"} {form name="thelia.order.delivery"}
{assign var="isPost" value="{$smarty.post|count}"} {assign var="isPost" value="{$smarty.post|count}"}
<form id="form-cart-delivery" action="{url path="/order/delivery"}" method="post" role="form" {form_enctype form=$form}> <form id="form-cart-delivery" action="{url path="/order/delivery"}" method="post" {form_enctype form=$form}>
{form_hidden_fields form=$form} {form_hidden_fields form=$form}

View File

@@ -29,7 +29,7 @@
{form name="thelia.order.coupon"} {form name="thelia.order.coupon"}
<form id="form-coupon" action="{url path="/order/coupon"}" method="post" role="form" {form_enctype form=$form}> <form id="form-coupon" action="{url path="/order/coupon"}" method="post" {form_enctype form=$form}>
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
@@ -163,7 +163,7 @@
{/form} {/form}
{form name="thelia.order.payment"} {form name="thelia.order.payment"}
<form id="form-cart-payment" action="{url path="/order/invoice"}" method="post" role="form" {form_enctype form=$form}> <form id="form-cart-payment" action="{url path="/order/invoice"}" method="post" {form_enctype form=$form}>
{form_hidden_fields form=$form} {form_hidden_fields form=$form}

View File

@@ -16,7 +16,7 @@
<article class="col-main" role="main" aria-labelledby="main-label"> <article class="col-main" role="main" aria-labelledby="main-label">
<h1 id="main-label" class="page-header">{intl l="Password Forgotten"}</h1> <h1 id="main-label" class="page-header">{intl l="Password Forgotten"}</h1>
{form name="thelia.front.customer.lostpassword"} {form name="thelia.front.customer.lostpassword"}
<form id="form-forgotpassword" action="{url path="/password"}" method="post" role="form"> <form id="form-forgotpassword" action="{url path="/password"}" method="post">
<p>{intl l="Please enter your email address below."} {intl l="You will receive a link to reset your password."}</p> <p>{intl l="Please enter your email address below."} {intl l="You will receive a link to reset your password."}</p>
{form_field form=$form field="email"} {form_field form=$form field="email"}

View File

@@ -137,7 +137,7 @@
</div> </div>
{form name="thelia.cart.add" } {form name="thelia.cart.add" }
<form id="form-product-details" action="{url path="/cart/add" }" method="post" role="form" class="form-product"> <form id="form-product-details" action="{url path="/cart/add" }" method="post" class="form-product">
{form_hidden_fields form=$form} {form_hidden_fields form=$form}
<input type="hidden" name="view" value="product"> <input type="hidden" name="view" value="product">
<input type="hidden" name="product_id" value="{$ID}"> <input type="hidden" name="product_id" value="{$ID}">

View File

@@ -15,7 +15,7 @@
<h1 id="main-label" class="page-header">{intl l="Create New Account"}</h1> <h1 id="main-label" class="page-header">{intl l="Create New Account"}</h1>
{form name="thelia.front.customer.create"} {form name="thelia.front.customer.create"}
<form id="form-register" class="form-horizontal" action="{url path="/register"}" method="post" role="form"> <form id="form-register" class="form-horizontal" action="{url path="/register"}" method="post">
{form_field form=$form field='success_url'} {form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on registration success *} <input type="hidden" name="{$name}" value="{url path="/account"}" /> {* the url the user is redirected to on registration success *}
{/form_field} {/form_field}

9
web/robots.txt Normal file
View File

@@ -0,0 +1,9 @@
# robots.txt for Thelia 2 (E-Commerce solution)
# @url: http://www.yourdomain.com
User-agent: *
Disallow: /admin
Disallow: /cart
Disallow: /404
#Sitemap: http://www.yourdomain.com/sitemap.xml