“I’m sick & tired of all the PHP hate. You can write sh*tty code in any language.” That’s our only PHP defender in the team, ranting. “Most times, problem’s the programmer, not the programming language.” Him again — mostly right. “Ever tried building something with Laravel? framework & community.” Awesome PHP’s made gigantic leaps since my early programming days. And I haven’t taken the time to jump back into its modern environment (been busy refactoring & prototyping). dabbling in Vue.js So today, that’s exactly what I’m going to do. How? . By creating a Laravel e-commerce site I’ll use Laravel-powered PyroCMS & Snipcart to help me do just that. It just so happens that I made a huge batch of spaghetti sauce this weekend. I’ll never be able to eat all of it, so why not sell the surplus online! In this tutorial, I’ll show you: How to set up a PyroCMS demo site How to add an e-commerce panel to PyroCMS How to display Snipcart products on your project’s frontend How to use webhooks & Laravel controllers inside PyroCMS How to use Snipcart’s custom validation during checkout Let’s see if my rusty PHP skills can outshine my cooking skills. Laravel & e-commerce: quick context For those who didn’t know already: . Laravel is an open source PHP web framework used to build sites & web apps It has a smooth learning curve, removes some quirks of building with PHP, has many modern built-in libraries. Some say it’s the Ruby on Rails PHP equivalent. Want to familiarize yourself with Laravel before starting this tuts? Check out this post — shows you how to build a simple MVC app < 10 min. With Laravel, you can leverage to manage dependencies & packages. Many useful packages will allow you to fast-track your Laravel app or site development. Think stuff like debugging, authentication, API interactions, etc. Sites like & are great resources to find helpful Laravel packages. Composer Packagist Packalyst E-commerce on Laravel? And of course, there are e-commerce packages for Laravel. Popular ones like and can help set up e-commerce functionalities on your Laravel app. Mage2 Aimeos So your e-commerce options with Laravel are pretty much: Build your own e-commerce application from the ground up with Laravel’s framework. Use e-comm. packages built to extend your app. Pick a Laravel-powered CMS and add custom e-commerce to it. . I could’ve done a whole e-commerce app in Laravel. But I didn’t have time to code everything from scratch — I needed an MVP to test the spaghetti sauce market ASAP! First one? Time-consuming . We might do it in another post! Second one? Actually interesting It’ll fast-track our development with useful shortcuts (PyroCMS scaffolding the site; Snipcart abstracting e-comm. logic & backend). Third one? This is what we’re doing here. I’m really glad to be operating inside a Laravel project for this demo. Unlike many of our JAMstack/static site tuts, it’ll be easy to handle any backend logic for our store. Editor’s note: if you’re building a simple subscription business with Laravel, check out Laravel Cashier , or our own subscription feature . A word on PyroCMS My previous experience with a PHP CMS wasn’t that great. However, I’d heard good stuff about Pyro here and there. And since I needed a Laravel-powered tool for this tuts, picking it was a no-brainer. is a PHP CMS built specifically for Laravel. It’s under the MIT license and comes equipped with a bunch of useful features. PyroCMS open source In the spirit of transparency, here are other Laravel-based CMS to consider: October CMS ( ) see our tuts AsgardCMS Lavalite TypiCMS Statamic ( ) see our tuts Laravel e-commerce tutorial: building a PyroCMS demo shop Pre-requisites For this tutorial, you’ll need: A basic understanding of PHP as a programming language A webserver set up with PHP and installed Composer A database for this project (I’m using MySQL) (forever free in Test mode) A Snipcart account Step 1: Installing PyroCMS Start by scaffolding a PyroCMS project with Composer. composer create-project pyrocms/pyrocms pyro_demo Set the root folder of your webserver to the project’s folder. Make sure it can write to , and folders. Those familiar with Laravel you'll recognize the directory structure. If you're new to PyroCMS, prepare to be impressed by how fast it is to have something up and running. public public/app bootstrap/cache storage Visit your website and use the built-in installer to configure Pyro with your site info and database settings. You can now remove the dependency from , then run . anomaly/installer-module composer.json composer update Step 2: Building an e-commerce panel for products Although we have a Laravel project to play with, PyroCMS suggests slicing new functionalities into . For a big project, making a few addons for non-related features would be a good idea. Here, we’ll create a products module using the : addons artisan command php artisan make:addon snipcart.module.products That will generate the folder . Most of the path from now on will be relative to this folder. addons/{your site slug}/snipcart/products-module At the core of Pyro is a concept of stream — essentially a collection of content. Our addon defines a stream that we scaffold with artisan: products php artisan make:stream products snipcart.module.products Those commands have generated some new elements. Let’s first look at the folder in our addon, where we only need to add a few things to have a complete product management backend. migrations Go ahead and define the fields of a product inside . They are defined using the . {date}_snipcart.module.products__create_products_fields.php built-in field types of Pyro Our products will have a SKU, name, price, description, image and tags: We must also add them to the parameter inside so they show up in our admin form. $assignments {date}_snipcart.module.products__create_products_stream.php We can type in the console to install the addon. That's enough to be able to add/edit products in the CMS admin! php artisan addon:install products Should you make changes to the migrations later on, you can refresh them using _php artisan migrate:refresh --addon=products_ . But there’s a lot more we can do to improve the editing experience. Let’s add the product image in the product listing. Edit in : $columns src/Product/Table/ProductTableBuilder.php We can show the stored value of the field by using its name, or format it by using . The latter evaluates the string and allows us to call presenter methods for our fields’ values (here: to show a dollar sign and to show a resized image). valuation currency preview Looking good! Step 3: Displaying products on the PyroCMS website We’ll add a view using ’s templating engine, then wire it with a controller and route. Create the product view that uses the default layout with a few Bootstrap classes in : Twig resources/views/products/index.twig Followed by a really simple controller in : src/Http/Controller/ProductsController.php For the route, add the route into to the ones generated for the admin: products src/ProductsModuleServiceProvider.php There we go! Looks nice if we visit : /products We also need a link to this page. Override the navigation template by creating the file : {project root}/resources/{site slug}/addons/pyrocms/starter-theme/views/partials/navigation.twig Here we copied the original template and simply added: Step 4: Integrating Snipcart with PyroCMS Just a few more steps to transform those buy buttons into . properly defined Snipcart products First we need somewhere to store our API Key. Add a setting entry for the module by creating the file : resources/config/setting.php This setting is accessible in the admin under . Settings Module > Modules > Products Module We’re ready to override the template in to add : scripts {project root}/resources/{site slug}/addons/pyrocms/starter-theme/views/partials/scripts.twig Snipcart's required files To inject Snipcart’s item attributes to buy buttons, modify to add a method inside : ProductPresenter buyButton src/Product/ProductPresenter.php There’s a lot going on in this file (especially if you’re new to Pyro): Receiving the through dependency injection in the Presenter's constructor HtmlBuilder Using our Product entry from $this->object Building a cropped image’s URL using utilities from Pyro’s FilesModule Transferring all product data to their respective Snipcart attributes Finally building the button ( ) element <a ...> We can now update our product view in to call the presenter: resources/views/products/index.twig {{ product.buyButton('Buy for '~product.price.currency(), {'class': 'btn btn-primary'})|raw }} Aaaand my delicious spaghetti sauce is now buyable! Step 5: Adding custom validation during checkout Selling food online — or anything else for that matter — often comes with various challenges. Frozen stuff can’t be shipped over long distances, for instance. Extra spicy stuff must come with a warning. And so on. So first let’s add a few dummy checks by using our new . We’ll prevent customers from ordering products too spicy for them: custom validation feature That code filters for validation events on the page and adds an error to products with a tag. It goes into and we add another line to : . cart-content spicy resources/js/validation.js scripts.twig {{ asset_add("scripts.js", "snipcart.module.products::js/validation.js") }} On to Frozen stuff checks and Laravel land now The ProductsController we made earlier actually extends a Laravel controller with a few goodies from PyroCMS added. When you look at the sources of from PyroCMS, you'll see all the stuff from the namespace wired to the controller. Now let's create a simple by extending the base Laravel controller directly and adding only the stuff we need. BaseController Illuminate shipping webhook Create this controller in : src/Http/Controller/ShippingController.php So only uses classes from . It's a plain old Laravel controller that checks Snipcart's input data and determines if we must return an error message or a shipping rate. Like for the , we add a route inside our module's service provider: . ShippingController Illuminate ProductsController 'webhooks/shipping' => 'Snipcart\ProductsModule\Http\Controller\ShippingController@webhook', Live demo & GitHub repo And we’re done! We covered lots of stuff here. But it should give you a broad overview of how to integrate Snipcart with PyroCMS + use more regular features of Laravel. See the open source repo on GitHub . See live demo here ! Closing thoughts The project and the admin interface were running in less than 3 hours, without any prior experience with Pyro on my end. The whole tuts ended up taking two days. Mostly because I really wanted to integrate Snipcart by injecting our scripts tags from the module instead of having to edit theme templates. I had a blast building the admin for this tuts. I don’t think that process can be made easier, so kudos to Pyro! Not knowing Laravel much, it was a bit hard for me to differentiate where PyroCMS ends and Laravel begins. You have to get familiar with PyroCMS’ source code to picture ways of how to accomplish things that aren’t easy to understand from only looking at the documentation. If I had more time to spend on this demo, I’d explore the many content management features of the admin. Lots can be accomplished directly from the admin without much code. A cool test would be to assign products to specifically tagged blog posts! Originally published this post on the Snipcart blog and in our newsletter .