Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dive Deep with Craft Plugins

mccombs
April 22, 2015

Dive Deep with Craft Plugins

mccombs

April 22, 2015
Tweet

More Decks by mccombs

Other Decks in Technology

Transcript

  1. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft TWILIGHT ZONE

    - 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
  2. DOCKING - HOME BASE SEA LEVEL 0 ft PHOTOGRAPHER >

    DESIGNER > FRONTEND > BACKEND Unicorn/split brain/jack of all trades - master of none
  3. DOCKING - HOME BASE SEA LEVEL 0 ft TAECHO GROUP

    taechogroup.com craftpl.us CRAFT PLUS (+ SUPER SECRET CRAFT PROJECT I CAN’T TALK ABOUT YET!)
  4. DOCKING - HOME BASE SEA LEVEL 0 ft PUBLIC PRIVATE

    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
  5. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft 260+ CRAFT

    PLUGINS!* *KNOWN AND RELEASED https:/ /straightupcraft.com/craft-plugins
  6. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    Extend your admin PUBLIC FACING Content helpers, forms etc. ECOMMERCE Quick overview
  7. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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.
  8. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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...
  9. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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.
  10. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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
  11. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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.
  12. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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.
  13. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    https:/ /github.com/davist11/craft-reroute/ REROUTE By: Trevor Davis Manage 301/302 redirects in the control panel.
  14. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ADMIN HELPERS

    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.
  15. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft PUBLIC FACING

    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!
  16. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft PUBLIC FACING

    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.
  17. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft PUBLIC FACING

    https:/ /github.com/xodigital/Formerly/ FORMERLY By: Marty Wallace Allow users to build their own forms and view form submissions
  18. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft PUBLIC FACING

    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.
  19. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft PUBLIC FACING

    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.
  20. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE http:/

    /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?
  21. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE http:/

    /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
  22. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE http:/

    /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.
  23. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE http:/

    /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
  24. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE https:/

    /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
  25. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE https:/

    /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
  26. SUNNY ZONE - EPIPELAGIC PLUGIN LANDSCAPE 660 ft ECOMMERCE https:/

    /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
  27. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft buildwithcraft.com/docs/plugins/introduction Plugin

    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
  28. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft buildwithcraft.com/docs/plugins/introduction Other

    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.
  29. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft Choose a

    name that’s easy to remember Plugin names should be 1 word or an abbreviation
  30. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft Lets get

    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
  31. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft Building a

    Craft Plugin Download or follow along at 
 github.com/mccombs/Craft-Plugin-Sample
  32. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft <?php namespace

    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
  33. TWILIGHT ZONE - MESOPELAGIC PLUGIN BASICS 3300 ft If so

    your plugin should be display below. (Admin area -> Settings -> Plugins) Are things working?
  34. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Things so

    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
  35. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Things so

    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
  36. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Things so

    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
  37. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft <?php namespace

    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
  38. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Give your

    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; } }
  39. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Give your

    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; } }
  40. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Give your

    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 %}
  41. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft The url

    follows the plugin name and folder structure /admin/sample Admin index page
  42. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Give your

    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’
  43. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Run your

    own layouts with this vacation Admin Template - Variation {% extends "sample/_layout" %} {% set title = "Sample Plugin" %} {% set selectedTab = 'index' %} {% set content %} <h1>h1 Heading</h1> {% endset %} Inside “index.html”
  44. DARK ZONE - BATHYPELAGIC PLUGIN STRUCTURE 13,200 ft Run your

    own layouts with this vacation Admin Template - Variation {% extends '_layouts/cp' %} {% set tabs = { dashboard: { label: “Dashboard"|t, url: url('casper/') }, } %} // Add Plugin resources here Inside “_layout.html”
  45. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft RECORD > MODEL

    > SERVICE > CONTROLLER > VARIABLE We’re going to create a quick CRUD Plugin

  46. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Time to start

    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
  47. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Matching up with

    our records Creating a model <?php namespace Craft; class SampleModel extends BaseModel { protected function defineAttributes() { return array( 'name' => AttributeType::String, 'desc' => AttributeType::String ); } }
  48. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft We need to

    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()
  49. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft We need to

    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)
  50. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft We need to

    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())
  51. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft We need to

    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)
  52. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft We need to

    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)
  53. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Lets catch those

    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)); } }
  54. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Lets catch those

    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(); } }
  55. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Interacting with our

    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()
  56. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Interacting with our

    Samples Our templates View all of our samples. 
 Links to create, edit and delete samples. index.html {% set samples = craft.sample.samples() %} {% if samples %} <h1 class="left">Your Samples</h1> <div class="elements"> <div class="tableview"> <table class="data"> <thead> <tr><th scope="col">Name</th> <th scope="col">Description</th> <th scope="col">Create Date</th> <th scope="col">Last Updated</th> <th scope="col">Actions</th> </tr></thead> <tbody> {% for sample in samples %} <tr> <td><a href="{{ url('sample/build/'~sample.id) }}”> {{ sample.name }}</a></td> <td>{{ sample.desc|trim[:50] }}...</td> <td>{{ sample.dateCreated|date('M. d, Y') }}</td> <td>{{ sample.dateUpdated|date('M. d, Y') }}</td> <td><a href="{{ url('sample/build/'~sample.id) }}" 
 class="action settings icon" title="Settings"></a> <a class="action delete icon" data-id="{{ sample.id }}" 
 title="Remove"></a></td> </tr> {% endfor %} </tbody> </table> </div> </div> {% else %} <h1>Oops you don't have any samples yet</h1> <p>Why don't you create one?</p> <a href="{{ url('sample/build/') }}">
 <button class="btn submit">Create Sample</button>
 </a> {% endif %}
  57. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Not this again

    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', ); } }
  58. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Interacting with our

    Samples Our templates Create and update our samples build.html {% if sampleId is not defined %}{% set sampleId = null %}{% endif %} {% if sample is not defined %} {% if sampleId %} {% set sample = craft.sample.getSample(sampleId) %} {% if not sample %}{% exit 404 %}{% endif %} {% else %} {% set sample = null %} {% endif %} {% endif %} {% set content %} <h1>Build a new sample</h1> <form method="post" action=""> <input type="hidden" name="action" value="sample/save" /> <input type="hidden" name="redirect" value="{{ url('sample') }}" /> <input type="hidden" name="sampleId" value="{{ sampleId }}" /> {{ forms.textField({ label: 'Sample Name'|t, required: true, name: 'name', id: 'name', value: sample ? sample.name : null, instructions: 'What should this sample be named?' }) }} {{ forms.textareaField({ label: 'Sample Description'|t, required: false, id: 'desc', name: 'desc', rows: '5', value: sample ? sample.desc : null, instructions: 'Provide a short write up about this sample' }) }} <div class="buttons"> <input type="submit" class="btn submit" value="{{ 'Save'|t }}"> </div> </form> {% endset %}
  59. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Here’s what it

    looks like now Updated template views - Index
  60. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Here’s what it

    looks like now Updated template views - Build
  61. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft Here’s what it

    looks like now Updated template views - Index (v2)
  62. ABYSS - ABYSSOPELAGIC PLUGIN CRUD 19,800 ft index.html Lots of

    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
  63. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Finally

    to the fun stuff! Bet you thought we’d never get here.
  64. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Tap

    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
  65. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Advanced

    Layouts Checkout Craft-> App -> Templates -> Layouts -> cp.html
  66. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Advanced

    Layouts Checkout Craft-> App -> Templates -> Layouts -> cp.html
  67. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Advanced

    Layouts Take Craft Data and graph it! - http://www.chartjs.org/
  68. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Advanced

    Layouts Do what works for your plugin and keep it in the Craft family!
  69. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Garnish

    Garnish is the built in JS modal that powers Craft Start here - http://craftcms.stackexchange.com/search?q=garnish
  70. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft Garnish

    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);
  71. TRENCH - HADOPELAGIC PLUGIN TIPS AND TRICKS 36,000 ft A

    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
  72. Signing off from the bottom of the plugin ocean! Follow

    me on twitter: @adammccombs https:/ /craftpl.us/plugins/dev-form Join Craft Plus as a dev!