├── app ├── commands │ └── .gitkeep ├── config │ ├── packages │ │ └── .gitkeep │ ├── local │ │ ├── cache.php │ │ ├── app.php │ │ ├── session.php │ │ └── database.php │ ├── config.php │ ├── compile.php │ ├── testing │ │ ├── cache.php │ │ └── session.php │ ├── workbench.php │ ├── view.php │ ├── queue.php │ ├── remote.php │ ├── auth.php │ ├── cache.php │ ├── database.php │ ├── mail.php │ ├── session.php │ └── app.php ├── controllers │ ├── .gitkeep │ ├── BaseController.php │ ├── HomeController.php │ ├── Api │ │ ├── ProductsController.php │ │ └── SearchController.php │ └── Admin │ │ └── SeoController.php ├── database │ ├── seeds │ │ ├── .gitkeep │ │ └── DatabaseSeeder.php │ ├── migrations │ │ └── .gitkeep │ └── production.sqlite ├── start │ ├── local.php │ ├── artisan.php │ └── global.php ├── storage │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── logs │ │ └── .gitignore │ ├── meta │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ └── views │ │ └── .gitignore ├── models │ ├── Category.php │ ├── Seo.php │ ├── User.php │ ├── Review.php │ └── Product.php ├── views │ ├── emails │ │ └── auth │ │ │ └── reminder.blade.php │ ├── partials │ │ └── sidebar │ │ │ └── categories.blade.php │ ├── categories │ │ └── single.blade.php │ ├── admin │ │ └── seo │ │ │ ├── list.blade.php │ │ │ └── edit.blade.php │ ├── layout.blade.php │ ├── products │ │ └── single.blade.php │ └── index.blade.php ├── tests │ ├── ExampleTest.php │ └── TestCase.php ├── lang │ └── en │ │ ├── pagination.php │ │ ├── reminders.php │ │ └── validation.php ├── filters.php └── routes.php ├── .gitattributes ├── public ├── packages │ └── .gitkeep ├── robots.txt ├── img │ ├── spinner.gif │ └── icons │ │ ├── banner │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── 5.jpg │ │ ├── product-1.jpg │ │ ├── product-2.jpg │ │ ├── product-3.jpg │ │ ├── product-4.jpg │ │ ├── product-5.jpg │ │ └── category-icon.png ├── .htaccess ├── vendor │ └── selectize │ │ ├── less │ │ ├── plugins │ │ │ ├── optgroup_columns.less │ │ │ ├── drag_drop.less │ │ │ ├── dropdown_header.less │ │ │ └── remove_button.less │ │ ├── selectize.default.less │ │ ├── selectize.legacy.less │ │ ├── selectize.bootstrap3.less │ │ ├── selectize.bootstrap2.less │ │ └── selectize.less │ │ └── css │ │ ├── selectize.css │ │ ├── selectize.bootstrap3.css │ │ ├── selectize.legacy.css │ │ └── selectize.default.css ├── css │ └── styles.css ├── js │ ├── main.js │ ├── expanding.js │ ├── jquery.charcounter.js │ ├── starrr.js │ └── vendor │ │ ├── spin.min.js │ │ └── backbone.paginator.min.js └── index.php ├── pagination.gif ├── .gitignore ├── server.php ├── phpunit.xml ├── composer.json ├── readme.md ├── bootstrap ├── paths.php ├── start.php └── autoload.php └── artisan /app/commands/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /app/config/packages/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/database/seeds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/packages/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/database/migrations/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/database/production.sqlite: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/start/local.php: -------------------------------------------------------------------------------- 1 | 'file', 5 | ); -------------------------------------------------------------------------------- /app/config/local/app.php: -------------------------------------------------------------------------------- 1 | true, 6 | 7 | ); 8 | -------------------------------------------------------------------------------- /app/config/local/session.php: -------------------------------------------------------------------------------- 1 | 'native', 6 | 7 | ); -------------------------------------------------------------------------------- /pagination.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/pagination.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap/compiled.php 2 | /vendor 3 | composer.phar 4 | composer.lock 5 | .DS_Store 6 | Thumbs.db -------------------------------------------------------------------------------- /public/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/spinner.gif -------------------------------------------------------------------------------- /public/img/icons/banner/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/banner/1.jpg -------------------------------------------------------------------------------- /public/img/icons/banner/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/banner/2.jpg -------------------------------------------------------------------------------- /public/img/icons/banner/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/banner/3.jpg -------------------------------------------------------------------------------- /public/img/icons/banner/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/banner/4.jpg -------------------------------------------------------------------------------- /public/img/icons/banner/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/banner/5.jpg -------------------------------------------------------------------------------- /public/img/icons/product-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/product-1.jpg -------------------------------------------------------------------------------- /public/img/icons/product-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/product-2.jpg -------------------------------------------------------------------------------- /public/img/icons/product-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/product-3.jpg -------------------------------------------------------------------------------- /public/img/icons/product-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/product-4.jpg -------------------------------------------------------------------------------- /public/img/icons/product-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/product-5.jpg -------------------------------------------------------------------------------- /public/img/icons/category-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/laravel-backbone-pagination/HEAD/public/img/icons/category-icon.png -------------------------------------------------------------------------------- /app/config/config.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'products' => 'Products', 8 | 'categories' => 'Categories', 9 | ), 10 | ); -------------------------------------------------------------------------------- /app/models/Category.php: -------------------------------------------------------------------------------- 1 | belongsToMany('Product'); 8 | } 9 | 10 | public function seo() 11 | { 12 | return $this->morphMany('Seo', 'seoble'); 13 | } 14 | } -------------------------------------------------------------------------------- /app/database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call('UserTableSeeder'); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/views/emails/auth/reminder.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Password Reset

8 | 9 |
10 | To reset your password, complete this form: {{ URL::to('password/reset', array($token)) }}. 11 |
12 | 13 | -------------------------------------------------------------------------------- /app/views/partials/sidebar/categories.blade.php: -------------------------------------------------------------------------------- 1 |

Shop Categories

2 | 3 |
4 | @foreach($categories as $category) 5 | {{{ $category->name }}} 6 | @endforeach 7 |
-------------------------------------------------------------------------------- /app/tests/ExampleTest.php: -------------------------------------------------------------------------------- 1 | client->request('GET', '/'); 13 | 14 | $this->assertTrue($this->client->getResponse()->isOk()); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /app/controllers/BaseController.php: -------------------------------------------------------------------------------- 1 | layout)) 13 | { 14 | $this->layout = View::make($this->layout); 15 | } 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes... 9 | RewriteRule ^(.*)/$ /$1 [L,R=301] 10 | 11 | # Handle Front Controller... 12 | RewriteCond %{REQUEST_FILENAME} !-d 13 | RewriteCond %{REQUEST_FILENAME} !-f 14 | RewriteRule ^ index.php [L] 15 | -------------------------------------------------------------------------------- /public/vendor/selectize/less/plugins/optgroup_columns.less: -------------------------------------------------------------------------------- 1 | .selectize-dropdown.plugin-optgroup_columns { 2 | .optgroup { 3 | border-right: 1px solid #f2f2f2; 4 | border-top: 0 none; 5 | float: left; 6 | .selectize-box-sizing(border-box); 7 | } 8 | .optgroup:last-child { 9 | border-right: 0 none; 10 | } 11 | .optgroup:before { 12 | display: none; 13 | } 14 | .optgroup-header { 15 | border-top: 0 none; 16 | } 17 | } -------------------------------------------------------------------------------- /app/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | array( 6 | 7 | 'mysql' => array( 8 | 'driver' => 'mysql', 9 | 'host' => 'localhost', 10 | 'database' => 'shop-pagination', 11 | 'username' => 'root', 12 | 'password' => 'root', 13 | 'charset' => 'utf8', 14 | 'collation' => 'utf8_unicode_ci', 15 | 'prefix' => '', 16 | ) 17 | ) 18 | ); 19 | -------------------------------------------------------------------------------- /app/start/artisan.php: -------------------------------------------------------------------------------- 1 | morphTo(); 10 | } 11 | 12 | public function updateFromInput() 13 | { 14 | $this->title = e(Input::get('title')); 15 | $this->description = e(Input::get('description')); 16 | $this->keywords = e(Input::get('keywords')); 17 | $this->save(); 18 | return true; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/config/compile.php: -------------------------------------------------------------------------------- 1 | .selectize-input > div.ui-sortable-placeholder { 3 | visibility: visible !important; 4 | background: #f2f2f2 !important; 5 | background: rgba(0,0,0,0.06) !important; 6 | border: 0 none !important; 7 | .selectize-box-shadow(inset 0 0 12px 4px #fff); 8 | } 9 | .ui-sortable-placeholder::after { 10 | content: '!'; 11 | visibility: hidden; 12 | } 13 | .ui-sortable-helper { 14 | .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); 15 | } 16 | } -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 18 | 'next' => 'Next »', 19 | 20 | ); -------------------------------------------------------------------------------- /app/config/testing/cache.php: -------------------------------------------------------------------------------- 1 | 'array', 19 | 20 | ); -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./app/tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/config/testing/session.php: -------------------------------------------------------------------------------- 1 | 'array', 20 | 21 | ); -------------------------------------------------------------------------------- /app/controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | "Passwords must be six characters and match the confirmation.", 17 | 18 | "user" => "We can't find a user with that e-mail address.", 19 | 20 | "token" => "This password reset token is invalid.", 21 | 22 | ); -------------------------------------------------------------------------------- /public/vendor/selectize/less/plugins/dropdown_header.less: -------------------------------------------------------------------------------- 1 | .selectize-dropdown-header { 2 | position: relative; 3 | padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; 4 | border-bottom: 1px solid @selectize-color-border; 5 | background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); 6 | .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); 7 | } 8 | .selectize-dropdown-header-close { 9 | position: absolute; 10 | right: @selectize-padding-dropdown-item-x; 11 | top: 50%; 12 | color: @selectize-color-text; 13 | opacity: 0.4; 14 | margin-top: -12px; 15 | line-height: 20px; 16 | font-size: 20px !important; 17 | } 18 | .selectize-dropdown-header-close:hover { 19 | color: darken(@selectize-color-text, 25%); 20 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "description": "The Laravel Framework.", 4 | "keywords": ["framework", "laravel"], 5 | "license": "MIT", 6 | "require": { 7 | "laravel/framework": "4.1.*" 8 | }, 9 | "autoload": { 10 | "classmap": [ 11 | "app/commands", 12 | "app/controllers", 13 | "app/models", 14 | "app/database/migrations", 15 | "app/database/seeds", 16 | "app/tests/TestCase.php" 17 | ] 18 | }, 19 | "scripts": { 20 | "post-install-cmd": [ 21 | "php artisan optimize" 22 | ], 23 | "post-update-cmd": [ 24 | "php artisan clear-compiled", 25 | "php artisan optimize" 26 | ], 27 | "post-create-project-cmd": [ 28 | "php artisan key:generate" 29 | ] 30 | }, 31 | "config": { 32 | "preferred-install": "dist" 33 | }, 34 | "minimum-stability": "dev" 35 | } 36 | -------------------------------------------------------------------------------- /app/config/workbench.php: -------------------------------------------------------------------------------- 1 | '', 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Workbench Author E-Mail Address 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Like the option above, your e-mail address is used when generating new 24 | | workbench packages. The e-mail is placed in your composer.json file 25 | | automatically after the package is created by the workbench tool. 26 | | 27 | */ 28 | 29 | 'email' => '', 30 | 31 | ); -------------------------------------------------------------------------------- /app/config/view.php: -------------------------------------------------------------------------------- 1 | array(__DIR__.'/../views'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Pagination View 21 | |-------------------------------------------------------------------------- 22 | | 23 | | This view will be used to render the pagination link output, and can 24 | | be easily customized here to show any view you like. A clean view 25 | | compatible with Twitter's Bootstrap is given to you by default. 26 | | 27 | */ 28 | 29 | // Bootstrap 3 paginator 30 | 'pagination' => 'pagination::slider-3', 31 | 32 | ); 33 | -------------------------------------------------------------------------------- /public/vendor/selectize/less/plugins/remove_button.less: -------------------------------------------------------------------------------- 1 | .selectize-control.plugin-remove_button { 2 | [data-value] { 3 | position: relative; 4 | padding-right: 24px !important; 5 | } 6 | [data-value] .remove { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | width: 17px; 12 | text-align: center; 13 | font-weight: bold; 14 | font-size: 12px; 15 | color: inherit; 16 | text-decoration: none; 17 | vertical-align: middle; 18 | display: inline-block; 19 | padding: @selectize-padding-item-y 0 0 0; 20 | border-left: 1px solid @selectize-color-item-border; 21 | .selectize-border-radius(0 2px 2px 0); 22 | .selectize-box-sizing(border-box); 23 | } 24 | [data-value] .remove:hover { 25 | background: rgba(0,0,0,0.05); 26 | } 27 | [data-value].active .remove { 28 | border-left-color: @selectize-color-item-active-border; 29 | } 30 | .disabled [data-value] .remove:hover { 31 | background: none; 32 | } 33 | .disabled [data-value] .remove { 34 | border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); 35 | } 36 | } -------------------------------------------------------------------------------- /public/css/styles.css: -------------------------------------------------------------------------------- 1 | .thumbnail{ padding: 0;} 2 | 3 | .carousel-control, .item{ 4 | border-radius: 4px; 5 | } 6 | 7 | .caption{ 8 | height: 130px; 9 | overflow: hidden; 10 | } 11 | 12 | .caption h4 13 | { 14 | white-space: nowrap; 15 | } 16 | 17 | .thumbnail img{ 18 | width: 100%; 19 | } 20 | 21 | .ratings 22 | { 23 | color: #d17581; 24 | padding-left: 10px; 25 | padding-right: 10px; 26 | } 27 | 28 | .thumbnail .caption-full { 29 | padding: 9px; 30 | color: #333; 31 | } 32 | 33 | footer{ 34 | margin-top: 50px; 35 | margin-bottom: 30px; 36 | } 37 | 38 | /* Search in the navigation bar */ 39 | 40 | .form-control.selectize-control{ 41 | height: 34px; 42 | } 43 | 44 | .selectize-dropdown-content img{ width:20px; height:20px; margin-right: 3px; float:left; } 45 | 46 | .selectize-control::before { 47 | -moz-transition: opacity 0.2s; 48 | -webkit-transition: opacity 0.2s; 49 | transition: opacity 0.2s; 50 | content: ' '; 51 | z-index: 2; 52 | position: absolute; 53 | display: block; 54 | top: 10px; 55 | right: 34px; 56 | width: 16px; 57 | height: 16px; 58 | background: url(../img/spinner.gif); 59 | background-size: 16px 16px; 60 | opacity: 0; 61 | } 62 | .selectize-control.loading::before { 63 | opacity: 1; 64 | } 65 | -------------------------------------------------------------------------------- /public/js/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('#searchbox').selectize({ 3 | valueField: 'url', 4 | labelField: 'name', 5 | searchField: ['name'], 6 | maxOptions: 10, 7 | options: [], 8 | create: false, 9 | render: { 10 | option: function(item, escape) { 11 | return '
' +escape(item.name)+'
'; 12 | } 13 | }, 14 | optgroups: [ 15 | {value: 'product', label: 'Products'}, 16 | {value: 'category', label: 'Categories'} 17 | ], 18 | optgroupField: 'class', 19 | optgroupOrder: ['product','category'], 20 | load: function(query, callback) { 21 | if (!query.length) return callback(); 22 | $.ajax({ 23 | url: root+'/api/search', 24 | type: 'GET', 25 | dataType: 'json', 26 | data: { 27 | q: query 28 | }, 29 | error: function() { 30 | callback(); 31 | }, 32 | success: function(res) { 33 | callback(res.data); 34 | } 35 | }); 36 | }, 37 | onChange: function(){ 38 | window.location = this.items[0]; 39 | } 40 | }); 41 | }); -------------------------------------------------------------------------------- /app/models/User.php: -------------------------------------------------------------------------------- 1 | getKey(); 30 | } 31 | 32 | /** 33 | * Get the password for the user. 34 | * 35 | * @return string 36 | */ 37 | public function getAuthPassword() 38 | { 39 | return $this->password; 40 | } 41 | 42 | /** 43 | * Get the e-mail address where password reminders are sent. 44 | * 45 | * @return string 46 | */ 47 | public function getReminderEmail() 48 | { 49 | return $this->email; 50 | } 51 | 52 | public function getRememberToken() 53 | { 54 | return $this->remember_token; 55 | } 56 | 57 | public function setRememberToken($value) 58 | { 59 | $this->remember_token = $value; 60 | } 61 | 62 | public function getRememberTokenName() 63 | { 64 | return 'remember_token'; 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Laravel Backbone - based in-place pagination demo Store application 2 | 3 | See demo at: http://demos.maxoffsky.com/ajax-pagination/ 4 | Tutorial at: http://maxoffsky.com/code-blog/in-place-pagination-using-backbone-js-laravel-shop-tutorial 5 | 6 | This application demonstrates usage of [Backbone Paginator](http://backbone-paginator.github.io/backbone.paginator/) Backbone.js plugin to provide the user with nice seamless pagination without a page refresh: 7 | ![pagination in action](https://raw.github.com/msurguy/laravel-backbone-pagination/master/pagination.gif) 8 | 9 | The pagination API controller is in app/controllers/Api/ProductsController.php 10 | The page using Backbone and pagination is in app/views/index.blade.php 11 | 12 | ### Installation instructions: 13 | - Download this repo 14 | - Set up a MySQL DB named 'shop-pagination' and import install.sql file into it, make sure you edit credentials in app/config/database.php to match yours 15 | - Open up terminal and CD into the folder of this repo 16 | - Run "php artisan serve" to run the application 17 | - Open up the browser and navigate to "localhost:8000" to see it in action 18 | 19 | ### Star this repo! 20 | 21 | The more people star my repos - the more I will give back to the community. 22 | 23 | ### Read more on my blog and follow on Twitter 24 | 25 | I post tutorials all the time on my blog : http://maxoffsky.com, stay updated on my Twitter: http://twitter.com/msurguy 26 | 27 | ### License 28 | 29 | The Laravel backbone pagination is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) 30 | -------------------------------------------------------------------------------- /app/controllers/Api/ProductsController.php: -------------------------------------------------------------------------------- 1 | count(); 36 | 37 | // Retrieve the products using Laravel's Eloquent ORM methods 38 | $products = $sortedProducts->take($perPage)->offset($offset)->get(array('slug','rating_cache','name','short_description','icon','banner','pricing')); 39 | 40 | // Return the results as JSON data 41 | return Response::json(array( 42 | 'data'=>$products->toArray(), 43 | 'total' => $count 44 | )); 45 | } 46 | } -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | 9 | /* 10 | |-------------------------------------------------------------------------- 11 | | Register The Auto Loader 12 | |-------------------------------------------------------------------------- 13 | | 14 | | Composer provides a convenient, automatically generated class loader 15 | | for our application. We just need to utilize it! We'll require it 16 | | into the script here so that we do not have to worry about the 17 | | loading of any our classes "manually". Feels great to relax. 18 | | 19 | */ 20 | 21 | require __DIR__.'/../bootstrap/autoload.php'; 22 | 23 | /* 24 | |-------------------------------------------------------------------------- 25 | | Turn On The Lights 26 | |-------------------------------------------------------------------------- 27 | | 28 | | We need to illuminate PHP development, so let's turn on the lights. 29 | | This bootstraps the framework and gets it ready for use, then it 30 | | will load up this application so that we can run it and send 31 | | the responses back to the browser and delight these users. 32 | | 33 | */ 34 | 35 | $app = require_once __DIR__.'/../bootstrap/start.php'; 36 | 37 | /* 38 | |-------------------------------------------------------------------------- 39 | | Run The Application 40 | |-------------------------------------------------------------------------- 41 | | 42 | | Once we have the application, we can simply call the run method, 43 | | which will execute the request and send the response back to 44 | | the client's browser allowing them to enjoy the creative 45 | | and wonderful application we have whipped up for them. 46 | | 47 | */ 48 | 49 | $app->run(); -------------------------------------------------------------------------------- /app/config/queue.php: -------------------------------------------------------------------------------- 1 | 'sync', 19 | 20 | 'failed' => array( 21 | 'database' => 'mysql', 'table' => 'failed_jobs', 22 | ), 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Queue Connections 27 | |-------------------------------------------------------------------------- 28 | | 29 | | Here you may configure the connection information for each server that 30 | | is used by your application. A default configuration has been added 31 | | for each back-end shipped with Laravel. You are free to add more. 32 | | 33 | */ 34 | 35 | 'connections' => array( 36 | 37 | 'sync' => array( 38 | 'driver' => 'sync', 39 | ), 40 | 41 | 'beanstalkd' => array( 42 | 'driver' => 'beanstalkd', 43 | 'host' => 'localhost', 44 | 'queue' => 'default', 45 | ), 46 | 47 | 'sqs' => array( 48 | 'driver' => 'sqs', 49 | 'key' => 'your-public-key', 50 | 'secret' => 'your-secret-key', 51 | 'queue' => 'your-queue-url', 52 | 'region' => 'us-east-1', 53 | ), 54 | 55 | 'iron' => array( 56 | 'driver' => 'iron', 57 | 'project' => 'your-project-id', 58 | 'token' => 'your-token', 59 | 'queue' => 'your-queue-name', 60 | ), 61 | 62 | ), 63 | 64 | ); 65 | -------------------------------------------------------------------------------- /app/config/remote.php: -------------------------------------------------------------------------------- 1 | 'production', 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Remote Server Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | These are the servers that will be accessible via the SSH task runner 24 | | facilities of Laravel. This feature radically simplifies executing 25 | | tasks on your servers, such as deploying out these applications. 26 | | 27 | */ 28 | 29 | 'connections' => array( 30 | 31 | 'production' => array( 32 | 'host' => '', 33 | 'username' => '', 34 | 'password' => '', 35 | 'key' => '', 36 | 'keyphrase' => '', 37 | 'root' => '/var/www', 38 | ), 39 | 40 | ), 41 | 42 | /* 43 | |-------------------------------------------------------------------------- 44 | | Remote Server Groups 45 | |-------------------------------------------------------------------------- 46 | | 47 | | Here you may list connections under a single group name, which allows 48 | | you to easily access all of the servers at once using a short name 49 | | that is extremely easy to remember, such as "web" or "database". 50 | | 51 | */ 52 | 53 | 'groups' => array( 54 | 55 | 'web' => array('production') 56 | 57 | ), 58 | 59 | ); -------------------------------------------------------------------------------- /app/models/Review.php: -------------------------------------------------------------------------------- 1 | 'required|min:10', 11 | 'rating'=>'required|integer|between:1,5' 12 | ); 13 | } 14 | 15 | // Relationships 16 | public function user() 17 | { 18 | return $this->belongsTo('User'); 19 | } 20 | 21 | public function product() 22 | { 23 | return $this->belongsTo('Product'); 24 | } 25 | 26 | // Scopes 27 | public function scopeApproved($query) 28 | { 29 | return $query->where('approved', true); 30 | } 31 | 32 | public function scopeSpam($query) 33 | { 34 | return $query->where('spam', true); 35 | } 36 | 37 | public function scopeNotSpam($query) 38 | { 39 | return $query->where('spam', false); 40 | } 41 | 42 | // Attribute presenters 43 | public function getTimeagoAttribute() 44 | { 45 | $date = \Carbon\Carbon::createFromTimeStamp(strtotime($this->created_at))->diffForHumans(); 46 | return $date; 47 | } 48 | 49 | // this function takes in product ID, comment and the rating and attaches the review to the product by its ID, then the average rating for the product is recalculated 50 | public function storeReviewForProduct($slug, $comment, $rating) 51 | { 52 | $product = Product::whereSlug($slug)->firstOrFail(); 53 | 54 | //$this->user_id = Auth::user()->id; 55 | $this->comment = $comment; 56 | $this->rating = $rating; 57 | $product->reviews()->save($this); 58 | 59 | // recalculate ratings for the specified product 60 | $product->recalculateRating($rating); 61 | } 62 | } -------------------------------------------------------------------------------- /app/models/Product.php: -------------------------------------------------------------------------------- 1 | hasMany('Review'); 9 | } 10 | 11 | public function categories() 12 | { 13 | return $this->belongsToMany('Category'); 14 | } 15 | 16 | public function seo() 17 | { 18 | return $this->morphMany('Seo', 'seoble'); 19 | } 20 | 21 | // Getters 22 | public function getIconAttribute() 23 | { 24 | return $this->attributes['icon'] ? url($this->attributes['icon']) : 'http://placehold.it/20x20'; 25 | } 26 | 27 | public function getBannerAttribute() 28 | { 29 | return $this->attributes['banner'] ? url($this->attributes['banner']) : 'http://placehold.it/300x240'; 30 | } 31 | 32 | // Scopes 33 | 34 | public function scopePublished($query) 35 | { 36 | return $query->where('published', true); 37 | } 38 | 39 | public function scopePopular($query) 40 | { 41 | return $query->published()->orderBy('rating_cache','desc'); 42 | } 43 | 44 | public function scopeNewest($query) 45 | { 46 | return $query->published()->orderBy('created_at','desc'); 47 | } 48 | 49 | public function scopeByname($query) 50 | { 51 | return $query->published()->orderBy('name','asc'); 52 | } 53 | 54 | // The way average rating is calculated (and stored) is by getting an average of all ratings, 55 | // storing the calculated value in the rating_cache column (so that we don't have to do calculations later) 56 | // and incrementing the rating_count column by 1 57 | 58 | public function recalculateRating($rating) 59 | { 60 | $reviews = $this->reviews()->notSpam()->approved(); 61 | $avgRating = $reviews->avg('rating'); 62 | $this->rating_cache = round($avgRating,1); 63 | $this->rating_count = $reviews->count(); 64 | $this->save(); 65 | } 66 | } -------------------------------------------------------------------------------- /app/views/categories/single.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layout') 2 | 3 | @section('title') 4 | {{{ $seo->title or 'Viewing Category '.$category->name }}} 5 | @endsection 6 | 7 | @section('description') 8 | {{{ $seo->description or 'My great category'}}} 9 | @endsection 10 | 11 | @section('keywords') 12 | {{{ $seo->keywords or 'default, keywords, for, my, category' }}} 13 | @endsection 14 | 15 | @section('content') 16 |
17 |
18 | @include('partials.sidebar.categories', array('categories' => $categories,'current' => $category->id)) 19 |
20 |
21 | @foreach($category->products as $product) 22 |
23 |
24 | 25 |
26 |

${{ number_format($product->pricing, 2);}}

27 |

{{$product->name}}

28 |

{{$product->short_description}}

29 |
30 |
31 |

{{$product->rating_count}} {{ Str::plural('review', $product->rating_count);}}

32 |

33 | @for ($i=1; $i <= 5 ; $i++) 34 | 35 | @endfor 36 |

37 |
38 |
39 |
40 | @endforeach 41 |
42 |
43 | @stop -------------------------------------------------------------------------------- /bootstrap/paths.php: -------------------------------------------------------------------------------- 1 | __DIR__.'/../app', 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Public Path 21 | |-------------------------------------------------------------------------- 22 | | 23 | | The public path contains the assets for your web application, such as 24 | | your JavaScript and CSS files, and also contains the primary entry 25 | | point for web requests into these applications from the outside. 26 | | 27 | */ 28 | 29 | 'public' => __DIR__.'/../public', 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Base Path 34 | |-------------------------------------------------------------------------- 35 | | 36 | | The base path is the root of the Laravel installation. Most likely you 37 | | will not need to change this value. But, if for some wild reason it 38 | | is necessary you will do so here, just proceed with some caution. 39 | | 40 | */ 41 | 42 | 'base' => __DIR__.'/..', 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Storage Path 47 | |-------------------------------------------------------------------------- 48 | | 49 | | The storage path is used by Laravel to store cached Blade views, logs 50 | | and other pieces of information. You may modify the path here when 51 | | you want to change the location of this directory for your apps. 52 | | 53 | */ 54 | 55 | 'storage' => __DIR__.'/../app/storage', 56 | 57 | ); 58 | -------------------------------------------------------------------------------- /app/views/admin/seo/list.blade.php: -------------------------------------------------------------------------------- 1 | @section('scripts') 2 | 9 | @stop 10 | 11 | @section('content') 12 |
13 | {{ Form::open(array('url'=>'admin/seo','method'=>'get','id'=>'selectForm','class'=>'form-horizontal'))}} 14 |
15 |

16 | SEO 17 |

18 |
19 |
20 |
21 |
22 |

23 | {{ Form::select('type', Config::get('config.seo_mapping'), $type, array('id'=> 'typeSelect' ,'class'=> 'form-control'))}} 24 |

25 |
26 | {{ Form::close()}} 27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | @foreach ($list as $item) 42 | 43 | 44 | 45 | @if($seo = $item->seo->first()) 46 | 47 | 48 | 49 | 50 | @else 51 | 52 | 53 | 54 | 57 | @endif 58 | 59 | @endforeach 60 | 61 |
NameSEO TitleSEO DescriptionSEO KeywordsAction
{{ $item->name }}{{$seo->title}}{{$seo->description}}{{$seo->keywords}}Edit 55 | Add 56 |
62 |
63 |
64 | @stop 65 | -------------------------------------------------------------------------------- /app/controllers/Api/SearchController.php: -------------------------------------------------------------------------------- 1 | & $item) { 14 | $item[$element] = $type; 15 | } 16 | return $data; 17 | } 18 | 19 | public function appendURL($data, $prefix) 20 | { 21 | // operate on the item passed by reference, adding the url based on slug 22 | foreach ($data as $key => & $item) { 23 | $item['url'] = url($prefix.'/'.$item['slug']); 24 | } 25 | return $data; 26 | } 27 | 28 | public function index() 29 | { 30 | $query = e(Input::get('q','')); 31 | 32 | if(!$query && $query == '') return Response::json(array(), 400); 33 | 34 | $products = Product::where('published', true) 35 | ->where('name','like','%'.$query.'%') 36 | ->orderBy('name','asc') 37 | ->take(5) 38 | ->get(array('slug','name','icon'))->toArray(); 39 | 40 | $categories = Category::where('name','like','%'.$query.'%') 41 | ->has('products') 42 | ->take(5) 43 | ->get(array('slug', 'name')) 44 | ->toArray(); 45 | 46 | // Data normalization 47 | $categories = $this->appendValue($categories, url('img/icons/category-icon.png'),'icon'); 48 | 49 | $products = $this->appendURL($products, 'products'); 50 | $categories = $this->appendURL($categories, 'categories'); 51 | 52 | // Add type of data to each item of each set of results 53 | $products = $this->appendValue($products, 'product', 'class'); 54 | $categories = $this->appendValue($categories, 'category', 'class'); 55 | 56 | // Merge all data into one array 57 | $data = array_merge($products, $categories); 58 | 59 | return Response::json(array( 60 | 'data'=>$data 61 | )); 62 | } 63 | } -------------------------------------------------------------------------------- /app/controllers/Admin/SeoController.php: -------------------------------------------------------------------------------- 1 | type = Input::get('type','products'); 11 | } 12 | 13 | public function index() 14 | { 15 | switch ($this->type) { 16 | case 'categories': 17 | $list = Category::with('seo')->get(array('id','name')); 18 | break; 19 | default: 20 | $list = Product::with('seo')->get(array('id','name')); 21 | break; 22 | } 23 | 24 | $this->layout->content = View::make('admin.seo.list', array('type' => $this->type, 'list' => $list)); 25 | } 26 | 27 | public function create() 28 | { 29 | $itemID = Input::get('id'); 30 | $item = $this->getItem($this->type, $itemID); 31 | $this->layout->content = View::make('admin.seo.edit', array('type' => $this->type, 'item'=>$item)); 32 | } 33 | 34 | public function store() 35 | { 36 | $itemID = Input::get('id'); 37 | 38 | $item = $this->getItem($this->type, $itemID); 39 | 40 | $seo = new Seo; 41 | $seo->updateFromInput(); 42 | $item->seo()->save($seo); 43 | 44 | return Redirect::to('admin/seo/'.$seo->id.'/edit?type='.$this->type.'&id='.$itemID)->with('seo_created', true); 45 | } 46 | 47 | public function edit($id) 48 | { 49 | $itemID = Input::get('id'); 50 | $item = $this->getItem($this->type, $itemID); 51 | $seo = Seo::find($id); 52 | 53 | $this->layout->content = View::make('admin.seo.edit', array('type' => $this->type, 'seo' => $seo,'item'=>$item)); 54 | } 55 | 56 | public function update($id) 57 | { 58 | $seo = Seo::find($id); 59 | 60 | $itemID = Input::get('id'); 61 | 62 | $seo->updateFromInput(); 63 | 64 | return Redirect::to('admin/seo/'.$id.'/edit?type='.$this->type.'&id='.$itemID)->with('seo_updated', true);; 65 | } 66 | 67 | public function getItem($type, $itemID) 68 | { 69 | switch ($type) { 70 | case 'categories': 71 | $item = Category::whereId($itemID)->get(array('id','name'))->first(); 72 | break; 73 | default: 74 | $item = Product::whereId($itemID)->get(array('id','name'))->first(); 75 | break; 76 | } 77 | 78 | return $item; 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /app/config/auth.php: -------------------------------------------------------------------------------- 1 | 'eloquent', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Authentication Model 23 | |-------------------------------------------------------------------------- 24 | | 25 | | When using the "Eloquent" authentication driver, we need to know which 26 | | Eloquent model should be used to retrieve your users. Of course, it 27 | | is often just the "User" model but you may use whatever you like. 28 | | 29 | */ 30 | 31 | 'model' => 'User', 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Authentication Table 36 | |-------------------------------------------------------------------------- 37 | | 38 | | When using the "Database" authentication driver, we need to know which 39 | | table should be used to retrieve your users. We have chosen a basic 40 | | default value but you may easily change it to any table you like. 41 | | 42 | */ 43 | 44 | 'table' => 'users', 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Password Reminder Settings 49 | |-------------------------------------------------------------------------- 50 | | 51 | | Here you may set the settings for password reminders, including a view 52 | | that should be used as your password reminder e-mail. You will also 53 | | be able to set the name of the table that holds the reset tokens. 54 | | 55 | | The "expire" time is the number of minutes that the reminder should be 56 | | considered valid. This security feature keeps tokens short-lived so 57 | | they have less time to be guessed. You may change this as needed. 58 | | 59 | */ 60 | 61 | 'reminder' => array( 62 | 63 | 'email' => 'emails.auth.reminder', 64 | 65 | 'table' => 'password_reminders', 66 | 67 | 'expire' => 60, 68 | 69 | ), 70 | 71 | ); -------------------------------------------------------------------------------- /app/filters.php: -------------------------------------------------------------------------------- 1 | $products, 16 | 'categories' => $categories 17 | )); 18 | }); 19 | 20 | // Route that shows an individual product by its slug 21 | Route::get('products/{slug}', function($slug) 22 | { 23 | $product = Product::whereSlug($slug)->firstOrFail(); 24 | $categories = Category::all(); 25 | $seo = $product->seo()->first(); 26 | 27 | // Get all reviews that are not spam for the product and paginate them 28 | $reviews = $product->reviews()->with('user')->approved()->notSpam()->orderBy('created_at','desc')->paginate(100); 29 | 30 | return View::make('products.single', array( 31 | 'product' => $product, 32 | 'reviews' => $reviews, 33 | 'categories'=> $categories, 34 | 'seo' => $seo 35 | )); 36 | }); 37 | 38 | // Route that handles submission of review - rating/comment 39 | Route::post('products/{slug}', array('before'=>'csrf', function($slug) 40 | { 41 | $input = array( 42 | 'comment' => Input::get('comment'), 43 | 'rating' => Input::get('rating') 44 | ); 45 | // instantiate Rating model 46 | $review = new Review; 47 | 48 | // Validate that the user's input corresponds to the rules specified in the review model 49 | $validator = Validator::make( $input, $review->getCreateRules()); 50 | 51 | // If input passes validation - store the review in DB, otherwise return to product page with error message 52 | if ($validator->passes()) { 53 | $review->storeReviewForProduct($slug, $input['comment'], $input['rating']); 54 | return Redirect::to('products/'.$slug.'#reviews-anchor')->with('review_posted',true); 55 | } 56 | 57 | return Redirect::to('products/'.$slug.'#reviews-anchor')->withErrors($validator)->withInput(); 58 | })); 59 | 60 | // Route that shows an individual category by its slug 61 | Route::get('categories/{slug}', function($slug) 62 | { 63 | $category = Category::whereSlug($slug)->firstOrFail(); 64 | $categories = Category::all(); 65 | $seo = $category->seo()->first(); 66 | 67 | return View::make('categories.single', array( 68 | 'category' => $category, 69 | 'categories'=> $categories, 70 | 'seo' => $seo 71 | )); 72 | }); 73 | 74 | Route::get('api/search', 'ApiSearchController@index'); 75 | -------------------------------------------------------------------------------- /bootstrap/start.php: -------------------------------------------------------------------------------- 1 | detectEnvironment(array( 28 | 29 | 'local' => array('localhost','Maxoffsky-PC'), 30 | 31 | )); 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Bind Paths 36 | |-------------------------------------------------------------------------- 37 | | 38 | | Here we are binding the paths configured in paths.php to the app. You 39 | | should not be changing these here. If you need to change these you 40 | | may do so within the paths.php file and they will be bound here. 41 | | 42 | */ 43 | 44 | $app->bindInstallPaths(require __DIR__.'/paths.php'); 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Load The Application 49 | |-------------------------------------------------------------------------- 50 | | 51 | | Here we will load the Illuminate application. We'll keep this is in a 52 | | separate location so we can isolate the creation of an application 53 | | from the actual running of the application with a given request. 54 | | 55 | */ 56 | 57 | $framework = $app['path.base'].'/vendor/laravel/framework/src'; 58 | 59 | require $framework.'/Illuminate/Foundation/start.php'; 60 | 61 | /* 62 | |-------------------------------------------------------------------------- 63 | | Return The Application 64 | |-------------------------------------------------------------------------- 65 | | 66 | | This script returns the application instance. The instance is given to 67 | | the calling script so we can separate the building of the instances 68 | | from the actual running of the application and sending responses. 69 | | 70 | */ 71 | 72 | return $app; 73 | -------------------------------------------------------------------------------- /public/vendor/selectize/less/selectize.default.less: -------------------------------------------------------------------------------- 1 | /** 2 | * selectize.default.css (v0.8.5) - Default Theme 3 | * Copyright (c) 2013 Brian Reavis & contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 6 | * file except in compliance with the License. You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 11 | * ANY KIND, either express or implied. See the License for the specific language 12 | * governing permissions and limitations under the License. 13 | * 14 | * @author Brian Reavis 15 | */ 16 | 17 | @import "selectize"; 18 | 19 | @selectize-color-item: #1da7ee; 20 | @selectize-color-item-text: #fff; 21 | @selectize-color-item-active-text: #fff; 22 | @selectize-color-item-border: #0073bb; 23 | @selectize-color-item-active: #92c836; 24 | @selectize-color-item-active-border: #00578d; 25 | @selectize-width-item-border: 1px; 26 | @selectize-caret-margin: 0 1px; 27 | 28 | .selectize-control { 29 | &.multi { 30 | .selectize-input { 31 | &.has-items { 32 | @padding-x: @selectize-padding-x - 3px; 33 | padding-left: @padding-x; 34 | padding-right: @padding-x; 35 | } 36 | &.disabled [data-value] { 37 | color: #999; 38 | text-shadow: none; 39 | background: none; 40 | .selectize-box-shadow(none); 41 | 42 | &, .remove { 43 | border-color: #e6e6e6; 44 | } 45 | .remove { 46 | background: none; 47 | } 48 | } 49 | [data-value] { 50 | text-shadow: 0 1px 0 rgba(0,51,83,0.3); 51 | .selectize-border-radius(3px); 52 | .selectize-vertical-gradient(#1da7ee, #178ee9); 53 | .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)"); 54 | &.active { 55 | .selectize-vertical-gradient(#008fd8, #0075cf); 56 | } 57 | } 58 | } 59 | } 60 | &.single { 61 | .selectize-input { 62 | .selectize-box-shadow(~"0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8)"); 63 | .selectize-vertical-gradient(#fefefe, #f2f2f2); 64 | } 65 | } 66 | } 67 | 68 | .selectize-control.single .selectize-input, .selectize-dropdown.single { 69 | border-color: #b8b8b8; 70 | } 71 | 72 | .selectize-dropdown { 73 | .optgroup-header { 74 | padding-top: @selectize-padding-dropdown-item-y + 2px; 75 | font-weight: bold; 76 | font-size: 0.85em; 77 | } 78 | .optgroup { 79 | border-top: 1px solid @selectize-color-dropdown-border-top; 80 | &:first-child { 81 | border-top: 0 none; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | setRequestForConsoleEnvironment(); 45 | 46 | $artisan = Illuminate\Console\Application::start($app); 47 | 48 | /* 49 | |-------------------------------------------------------------------------- 50 | | Run The Artisan Application 51 | |-------------------------------------------------------------------------- 52 | | 53 | | When we run the console application, the current CLI command will be 54 | | executed in this console and the response sent back to a terminal 55 | | or another output device for the developers. Here goes nothing! 56 | | 57 | */ 58 | 59 | $status = $artisan->run(); 60 | 61 | /* 62 | |-------------------------------------------------------------------------- 63 | | Shutdown The Application 64 | |-------------------------------------------------------------------------- 65 | | 66 | | Once Artisan has finished running. We will fire off the shutdown events 67 | | so that any final work may be done by the application before we shut 68 | | down the process. This is the last thing to happen to the request. 69 | | 70 | */ 71 | 72 | $app->shutdown(); 73 | 74 | exit($status); -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | 17 | @import "selectize"; 18 | 19 | @selectize-font-size: 13px; 20 | @selectize-line-height: 20px; 21 | 22 | @selectize-color-input-full: #f2f2f2; 23 | @selectize-color-item: #b8e76f; 24 | @selectize-color-item-text: #3d5d18; 25 | @selectize-color-item-border: #74b21e; 26 | @selectize-color-item-active: #92c836; 27 | @selectize-color-item-active-border: #6f9839; 28 | @selectize-color-highlight: rgba(255,237,40,0.4); 29 | @selectize-color-dropdown-item-active: #fffceb; 30 | @selectize-color-dropdown-item-active-text: @selectize-color-text; 31 | @selectize-color-optgroup: #f8f8f8; 32 | @selectize-color-optgroup-text: @selectize-color-text; 33 | @selectize-width-item-border: 1px; 34 | 35 | @selectize-padding-x: 10px; 36 | @selectize-padding-y: 10px; 37 | @selectize-padding-item-x: 5px; 38 | @selectize-padding-item-y: 1px; 39 | @selectize-padding-dropdown-item-x: 10px; 40 | @selectize-padding-dropdown-item-y: 7px; 41 | @selectize-margin-item-x: 4px; 42 | @selectize-margin-item-y: 4px; 43 | 44 | .selectize-control { 45 | &.multi { 46 | .selectize-input [data-value] { 47 | text-shadow: 0 1px 0 rgba(255,255,255,0.1); 48 | .selectize-border-radius(3px); 49 | .selectize-vertical-gradient(#b8e76f, #a9e25c); 50 | .selectize-box-shadow(0 1px 1px rgba(0,0,0,0.1)); 51 | &.active { 52 | .selectize-vertical-gradient(#92c836, #7abc2c); 53 | } 54 | } 55 | } 56 | &.single { 57 | .selectize-input { 58 | .selectize-box-shadow(~"inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1)"); 59 | .selectize-vertical-gradient(#f5f5f5, #efefef); 60 | } 61 | } 62 | } 63 | 64 | .selectize-control.single .selectize-input, .selectize-dropdown.single { 65 | border-color: #b8b8b8; 66 | } 67 | 68 | .selectize-dropdown { 69 | .optgroup-header { 70 | font-weight: bold; 71 | font-size: 0.8em; 72 | border-bottom: 1px solid @selectize-color-dropdown-border-top; 73 | border-top: 1px solid @selectize-color-dropdown-border-top; 74 | } 75 | } -------------------------------------------------------------------------------- /app/start/global.php: -------------------------------------------------------------------------------- 1 | 3 | 22 | @stop 23 | 24 | @section('content') 25 |
26 |
27 | @if(Session::has('seo_created')) 28 |
29 |
The SEO data has been created!
30 |
31 | @endif 32 | 33 | @if(Session::has('seo_updated')) 34 |
35 |
The SEO data has been updated!
36 |
37 | @endif 38 |
39 |
40 | 41 |
42 |
43 | {{ Form::open(array('url'=>'admin/seo','method'=>'get','id'=>'selectForm','class'=>'form-vertical'))}} 44 | {{ Form::select('type', Config::get('config.seo_mapping'), $type, array('id'=> 'typeSelect' ,'class'=> 'form-control'))}} 45 | {{ Form::close()}} 46 |
47 |
48 | Back to the list 49 |
50 |
51 |
52 |
53 |
54 | @if(isset($seo)) 55 | {{ Form::model($seo, array('url' => 'admin/seo/'.$seo->id, 'method' => 'put')) }} 56 | @else 57 | {{ Form::open(array('url' => 'admin/seo')) }} 58 | @endif 59 | 60 | Editing SEO for {{ $item->name }} in {{ Config::get('config.seo_mapping.'.$type) }} 61 | 62 |
63 | {{Form::label('title')}} 64 | {{ Form::text('title', null ,array('class'=>'form-control', 'placeholder'=>'SEO Title'))}} 65 |
66 | 67 |
68 | {{ Form::label('keywords')}} 69 | {{ Form::text('keywords', null ,array('class'=>'form-control', 'placeholder'=>'SEO Keywords'))}} 70 |
71 | 72 |
73 | {{ Form::label('description')}} 74 | {{ Form::textarea('description', null ,array('class'=>'form-control', 'placeholder'=>'SEO Description','rows' => 4))}} 75 |
76 | 77 | {{ Form::hidden('type', $type)}} 78 | {{ Form::hidden('id', $item->id)}} 79 | 80 |
81 | {{ Form::submit('Submit', array('class'=>'btn btn-default'))}} 82 |
83 | 84 | {{ Form::close()}} 85 |
86 |
87 | @stop 88 | -------------------------------------------------------------------------------- /public/js/expanding.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Autosize v1.18.1 - 2013-11-05 3 | Automatically adjust textarea height based on user input. 4 | (c) 2013 Jack Moore - http://www.jacklmoore.com/autosize 5 | license: http://www.opensource.org/licenses/mit-license.php 6 | */ 7 | (function(e){var t,o={className:"autosizejs",append:"",callback:!1,resizeDelay:10},i='