- MESOPELAGIC PLUGIN BASICS 3300 ft DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft
MY PLUGINS CASPER Blank slate plugin CRAFT NAV Flexible Navigation New version coming soon! LEMMINGS Plugin dev kick starter New version coming soon! 404 FINDER Record 404 errors STRIPE SUBSCRIPTIONS Monthly subscription service EVENT CHECKIN APP IP & Location recording VENDOR APPLICATIONS Approvals & Rejections EVENTBRITE SYNC User/data creation
CONTROL PANEL CSS By: Double Secret Agency https:/ /github.com/lindseydiloreto/craft-cpcss/ Control panel CSS allows you to customize the control panel to your liking in a very clean way. You can change colors, show/hide elements and style the admin panel for clients.
https:/ /github.com/lindseydiloreto/craft-matrixcolors/ MATRIX COLORS By: Double Secret Agency Easily identify your matrix blocks, by assigning a different color for each block type...
https:/ /github.com/jmuspratt/craft-fieldguide/ FIELD GUIDE By: James Muspratt Field Guide adds a tab to your Dashboard that lists all your fields in a single page, grouped by section. Matrix sub-fields are displayed in indented rows and and all field names are linked to their editing pages.
https:/ /github.com/engram-design/FieldManager/ FIELD MANAGER By: Josh Crawford Field Manager is a Craft CMS plugin to help make it easy to manage your fields and field groups. ..functionality revolves around cloning fields and field groups
https:/ /github.com/focuslabllc/craft-field-cheat-sheet CRAFT FIELD CHEAT SHEET By: Erik Reagan The Craft Field Cheat Sheet brings code samples into context to the site you're actually working on. The code you're shown actually uses your custom field names rather than sample field names.
https:/ /straightupcraft.com/craft-plugins/cp-nav CONTROL PANEL NAV By: Josh Crawford Control Panel Nav is a Craft CMS plugin to help manage your Control Panel navigation.
https:/ /dukt.net/craft/analytics ANALYTICS By: Dukt Analytics plugin connects to Google Analytics and displays colorful report widgets of your website's activity. The widget lets you explore most of your Google Analytics statistics, track your visitors in real-time, and pin the important data that you want to keep under your eyes.
https:/ /craftpl.us/plugins/smart-map/ SMART MAP By: Double Secret Agency Easily manage geographic points & maps!- Render a Google map of your locations - Sort your locations from closest to farthest- Add marker info bubbles - Completely customize your maps- Automatically detect your user's location - And much more good stuff!
http:/ /sprout.barrelstrengthdesign.com/craft-plugins/forms SPROUT FORMS By: Barrelstrengthdesign Use Sprout Forms to create forms for Contacts, Projects, Leads, Surveys, Contests, Registration, RSVPs, or whatever else you need. Add any number of fields to your forms and create as many forms as you want.
https:/ /github.com/ehousestudio/craft_hacksaw/ HACKSAW By: Ryan Shrum A migrated (and improved) version (for Craft CMS) of Brett DeWoody's Hacksaw for ExpressionEngine. This plugin adds a Twig filter to take your entry's content and whittle it down to a more manageable size. It strips the HTML and limits the excerpts by character count, word count or cutoff marker.
https:/ /craftpl.us/plugins/pic-puller-for-instagram PIC PULLER FOR INSTAGRAM By: John F Morton Integrates Instagram into your Craft site. Easily add image and video feeds for your site. Use the Instagram Image Browser Fieldtype to add images and video into your Craft entries.
/craftcms.stackexchange.com/questions/299/what-is-the-current- landscape-regarding-e-commerce-plugins-for-craft/301#301 WHAT IS THE CURRENT LANDSCAPE REGARDING E-COMMERCE PLUGINS FOR CRAFT?
/sprout.barrelstrengthdesign.com/craft-plugins/commerce SPROUT ECOMMERCE By: Barrelstrengthdesign Manage your products with a clean, intuitive interface and all the power of Craft Sections and custom fields. Your products and orders exist right alongside your web content, giving you fine-grained control over how you integrate your e-commerce needs with your content. IN BETA
/squarebit.co.uk/software/craft/charge CHARGE By: Squarebit Charge is the best way to add Stripe payments to your Craft site. Sell your digital products direct on your Craft site. After successful payment you can deliver any digital files to the user safely and securely.
/buildwithmarket.com/ MARKET By: Market Market seeks to grow into the most sophisticated and easy to use commerce plugin. Currently in beta, we have a fantastic platform to build on. From simple products, to complex products with variations and options, Market can handle it all. IN BETA
/github.com/snipcart/snipcart-craft-webhooks-plugin SNIPTCART By: Charles Ouellet Sample plugin to allow inventory management in a Craft application using Snipcart. 3RD PARTY SERVICE
/github.com/FoxyCart/foxycart-craft FOXYCART By: Charles Ouellet This plugin adds in a number of FoxyCart features to Craft to make it easier for you to add a FoxyCart powered checkout to your site 3RD PARTY SERVICE
/github.com/lindseydiloreto/craft-moltin MOLTIN PLUGIN By: Double Secret Agency Moltin is a cutting-edge eCommerce solution. While relatively young, it's built upon a single, brilliant concept: a comprehensive eCommerce API. All of the front-end components are left for you to design at will. 3RD PARTY SERVICE
Basics PRIMARY PLUGIN CLASS The primary plugin class lets you install and enable your plugin. Start here 1 VARIABLES Public facing info or actions {{ craft.pluginName.variable }} 2 3 SERVICES Core functionality of your plugin craft()->serviceHandle->methodName() CONTROLLERS 4 HTTP Requests Middle man between actions & services MODELS 5 Models represent your stored data RECORDS 6 Install and record data inside the Craft database
plugin types Not happy with the 18 different fields craft gives you out of the box? Build your own. _ [ ] FIELD TYPES DASHBOARD WIDGETS Provide overview data to the dashboard that you can see when you first login. Keep it simple.
some things out of the way. 1. Plugins must have unique names (folder names and handles) 2. Plugins must have a primary Plugin Class before they can be installed or enabled 3. Plugins can run functions on init() or after events happen in Craft 4. Plugins can be used to embed custom variables like {{ craft.pluginName.variable }} 5. Plugins utilize their own templates to build out custom areas in the Craft Admin area 6. Plugins can act as field types and dashboard widgets 7. Plugins run custom actions that can be triggered manually or upon hooks and events Plugin Basics
Craft; class SamplePlugin extends BasePlugin { function getName() { return Craft::t('Sample Plugin'); } function getVersion() { return '1.0'; } function getDeveloper() { return 'Adam McCombs'; } function getDeveloperUrl() { return 'http://crafpl.us'; } } This file is required to list and install a plugin A Primary Plugin Class
different yet so the same Traditional MVC vs. Craft The brains of the operation. Organize data for output. CONTROLLER Ready for the world to see. Templates & HTML VIEW Data storage, data queries Manipulation and control. MODEL TRADITIONAL MVC DATABASE BROWSER
different yet so the same Traditional MVC vs. Craft THE CRAFT WAY Install and recording RECORD 1 to 1 with records MODEL Typically point to services VARIABLE Always accessible SERVICE Grab actions and call services CONTROLLER Forms & actions ACTION URLS Embed your variables PUBLIC TEMPLATES Work with your plugin ADMIN TEMPLATES
different yet so the same Traditional MVC vs. Craft THE CRAFT WAY Install and recording RECORD 1 to 1 with records MODEL Typically point to services VARIABLE Always accessible SERVICE Grab actions and call services CONTROLLER Forms & actions ACTION URLS Embed your variables PUBLIC TEMPLATES Work with your plugin ADMIN TEMPLATES MODEL CONTROLLER VIEW
Craft; /** * Sample Variable */ class SampleVariable { /** * Output Hello World * {{ craft.sample.hello }} */ public function hello() { return 'Hello world!'; } } This allows you to use variables like {{ craft.sample.hello }} Outputting a simple variable
plugin life within the Craft Admin panel Building an Admin Template Step 1) - Add “hasCpSection()” to your primary plugin class <?php namespace Craft; class SamplePlugin extends BasePlugin { function getName() { return Craft::t('Sample Plugin'); } . . . function hasCpSection() { return true; } }
plugin life within the Craft Admin panel Building an Admin Template Step 1) - Add “hasCpSection()” to your primary plugin class Step 2) - Create a “templates” folder with an “index.html” file <?php namespace Craft; class SamplePlugin extends BasePlugin { function getName() { return Craft::t('Sample Plugin'); } // . . . function hasCpSection() { return true; } }
plugin life within the Craft Admin panel Building an Admin Template Step 1) - Add “hasCpSection()” to your primary plugin class Step 2) - Create a “templates” folder with an “index.html” file Step 3) - Inside “index.html” include the following {% extends '_layouts/cp' %} {% set tabs = { index: { label: “Index"|t, url: url('sample/') }, } %} {% set title = "Sample Plugin" %} {% set selectedTab = 'index' %} {% set content %} <h1>h1 Heading</h1> {% endset %}
plugin life within the Craft Admin panel Building an Admin Template {% extends '_layouts/cp' %} {% set tabs = { index: { label: “Index"|t, url: url('sample/') }, } %} {% set title = "Sample Plugin" %} {% set selectedTab = 'index' %} {% set content %} <h1>h1 Heading</h1> {% endset %} Link to within other plugin pages you create Set tabs (array) Give your template page a name Set title Which tab should be identified as selected? Set selectedTab Your amazing content Set content This tells Craft which template to load Extends ‘_layout’
recording some data Creating a record Create a records folder with a “SampleRecord.php” file inside <?php namespace Craft; class SampleRecord extends BaseRecord { public function getTableName() { return 'sample'; } protected function defineAttributes() { return array( 'name' => array( AttributeType::String, 'required' => true), 'desc' => array( AttributeType::String, 'column' => ColumnType::Text), ); } } This will do two things 1) Upon Plugin install Craft will create this new table 2) The table created will create the defined attributes
access our data Creating a service <?php namespace Craft; class SampleService extends BaseApplicationComponent { public function samples() { $lemmings = craft()->db->createCommand() ->select('*') ->from('sample') ->where('') ->queryAll(); return $samples; } } Return all of our samples so we can display a for loop samples()
access our data Creating a service <?php namespace Craft; class SampleService extends BaseApplicationComponent { public function getSample($sampleId) { if ($record = $this->record ->findByPk($sampleId)) { return SampleModel:: populateModel($record); } } } Grab a single sample using a provided sample ID getSample($sampleId)
access our data Creating a service <?php namespace Craft; class SampleService extends BaseApplicationComponent { $model = new SampleModel(); $model->setAttributes($attributes); return $model; } Simple. Create a Sample using the attributes we provide create($attributes = array())
access our data Creating a service <?php namespace Craft; class SampleService extends BaseApplicationComponent { public function save(SampleModel &$model) { if ($id = $model->getAttribute('id')) { if (null === ($record = $this->record->findByPk($id))) { throw new Exception( Craft::t('Can\'t find a sample with ID "{id}"', array('id' => $id))); } } else { $record = new SampleRecord(); } $record->setAttributes($model->getAttributes()); if ($record->save()) { // update id on model (for new records) $model->setAttribute('id', $record->getAttribute('id')); return true; } else { $model->addErrors($record->getErrors()); return false; } } Save (or update if you prefer) save(SampleModel &$model)
access our data Creating a service <?php namespace Craft; class SampleService extends BaseApplicationComponent { $record = SampleRecord::model() ->findByPk($id); if ($record) { $record->delete(); } } Simple. Delete a Sample. delete($id)
actions Creating a controller Catch our save action and go actionSave() <?php namespace Craft; class SampleController extends BaseController { public function actionSave() { if ($id = craft()->request->getPost('sampleId')) { $model = craft()->sample->getSample($id); } else { $model = craft()->sample->create(); } $data = craft()->request->getPost(); $model->name = $data['name']; $model->desc = $data['desc']; if($model->validate()) { craft()->sample->save($model); craft()->userSession->setNotice( Craft::t('Sample saved.')); return $this->redirectToPostedUrl(); } else { craft()->userSession->setError( Craft::t('There was a problem with your submission, please check the form and try again!')); craft()->urlManager-> setRouteVariables(array('sample' => $model)); } }
actions Creating a controller Grab our Sample ID from our post and delete actionDelete() <?php namespace Craft; class SampleController extends BaseController { public function actionDelete() { $this->requirePostRequest(); $id = craft()->request-> getRequiredPost('id'); craft()->sample->delete($id); craft()->end(); } }
Samples Updating our variables <?php namespace Craft; class SampleVariable { // Output Hello World // {{ craft.sample.hello }} public function hello() { return 'Hello world!'; } // Grab all Samples public function samples() { return craft()->sample->samples(); } // Grab an individual Sample public function getSample($sampleId) { return craft()->sample-> getSample($sampleId); } } Will return ‘Hello world!’ when using {{ craft.sample.hello }} We’re keeping this because it’s cool hello() Links over to services and grabs an array of our samples samples() Links over to services and grabs a single sample getSample()
Primary Plugin Class This also allows you to pass in the dynamic values like sampleID Also know as a hook. You must set Dynamic CP Routes - exclusively <?php namespace Craft; class SamplePlugin extends BasePlugin { // … function registerCpRoutes() { return array( 'sample/build\/(?P<sampleId>\d+)' => 'sample/build', ); } }
files - lots of possibilities Here’s a quick recap {% set samples = craft.sample.samples() %} Install Created “sample” table based off SampleRecord.php or empty message build.html New Sample or update an existing Sample Action: Delete -> Controller (ajax) Action: Save -> Controller
into that craft power! Hooks & events Events Events let you piggy back on actions happening within craft. Hooks Customize Craft even further than what comes out of the box. modifyEntrySortableAttributes() Modify the attributes that entries can be sorted by in the Control Panel addUserAdministrationOptions() Add additional admin options to the Edit User page, which will show up when clicking on the gear icon menu at the top-right of the page. email.onSendEmail() Trigger an action every time an email is sent. users.onSaveUser Trigger an action when a user is saved entries.onSaveEntry Trigger an action when a entry is saved
Garnish is the built in JS modal that powers Craft Start here - http://craftcms.stackexchange.com/search?q=garnish var $div = $('<div class="modal">...</div>'); var myModal = new Garnish.Modal($div);
word on Commercial Plugins We need you! SEO Events eCommerce Publishing workflows Social Sharing Social Sharing Digital Product Downloads Advanced Tagging Image Optimization Filterable entries Memberships & Subscriptions