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

Really Rapid Admin Application Development

Really Rapid Admin Application Development

How many ways can you generate a CakePHP Admin interface? A summary of the available methods, as well as an intro to CakeAdmin, a class-based admin generation tool.

Jose Diaz-Gonzalez

September 04, 2011
Tweet

More Decks by Jose Diaz-Gonzalez

Other Decks in Technology

Transcript

  1. ~WHOAMI • Jose Diaz-Gonzalez • Resident IRC Troll (savant) •

    Rants at http://josediazgonzalez.com • Harasses as @savant • Codes as josegonzalez on github • Works at @seatgeek ➘ me ➘ not me
  2. WHO IS THIS TALK FOR? • Anyone building CMS’ for

    a living • Those needing quick, extensible CRUD applications • Anyone looking for a boring challenge
  3. WHAT THE HELL IS THIS? • var $scaffold = true;

    • ../cake/console/cake bake • cake bake skeletons • admin generation
  4. SCAFFOLDING • Generic application auto-generation • In CakePHP, introspects the

    Model::schema() and relationships to pull in data • Dumb, never recommended for production, not easy to manipulate
  5. EXTENDING THIS? • Introspects model; add callbacks/validation rules/behaviors • _*Scaffold()

    Callbacks • Custom app/controller/scaffold.php class • Customize app/views/scaffolds/* views • 2.0 gets cooler scaffold
  6. FIN

  7. SCAFFOLD DRAWBACKS • Little to no usage documentation • Hard

    to customize • Easier to add generic methods in AppController
  8. GENERIC METHODS • Create index()/view()/add()/edit()/delete() methods in your AppController •

    Have callbacks to disable in specific Controllers • Able to override in child Controllers
  9. /**  *  Handles  index  requests.  *  *  @return  void  *

     @access  public  */ public  function  index()  {        //  Only  do  this  work  if  our  concrete  controller  has  not.        if  (!isset($this-­‐>viewVars[Inflector::pluralize($this-­‐>modelClass)]))  {                $this-­‐>set(array(                        Inflector::pluralize($this-­‐>modelClass)  =>  $this-­‐>paginate(                                $this-­‐>modelClass,                                /**                                  *  Here  we  toss  in  any  conditions  that  were  found  as  named                                  *  parameters  and  which  match  up  to  a  column  in  the  model                                  *  schema.                                  */                                array_intersect_key(                                        $this-­‐>params['named'],                                        $this-­‐>{$this-­‐>modelClass}-­‐>schema()                                )                        )                ));        } } From https://github.com/joebeeson/crumbs/blob/develop/app_controller.php
  10. class  PostsController  extends  AppController  {        protected  $disabledActions

     =  array('index',  'add',  'edit',  'changelog');        public  function  beforeFilter()  {                if  (in_array($this-­‐>params['action'],  $this-­‐>disabledActions))  {                        $this-­‐>cakeError('404');                }        } } disabling mocked methods
  11. CAVEATS • Has to be generic enough to use across

    controllers • Only portable if built as a plugin library (ie. LazyModel) • Must remember to build disabling code
  12. CAKE BAKE • You can now view the generated code

    and modify at will • Have to re-bake constantly • Everyone uses it; No one customizes it • Same issues as Scaffold • NOT === var $scaffold
  13. BAD CAKE BAKE • Lets use Model::scaffold = -­‐1 please

    • Generated view() can result in an empty page • Generated delete() lets crawlers potentially auto-delete site • Model::read() usage is evil • Asks too many questions; Can’t I just answer once and rebake?
  14. EXTENDING THIS? • Templates: app/vendors/shells/templates • Models are simple to

    access in templates • Do you follow “conventions” or allow configuration? • May need custom shell for extra configuration
  15. CAKE SKELETONS • Can’t use in existing applications • Assume

    you’ll always follow the same conventions • Hard to upgrade bootstrapped apps in automated fashion • Good for “chop-shops” and freelancers on new apps
  16. EXTENDING THIS? • Copy cake/console/templates/skel to app/ vendors/templates/skeletor • Add

    plugins, create migrations/schema files • Generate generic models/controllers/views • Customize the HTML/CSS • GITHUB
  17. EXISTING CAKE BAKE SKELETONS • Andy Dawson’s Skel • Jon

    Bradley’s cake-skel • Dean Soffer’s BakingPlate • Jose Gonzalez’s AppSkellington
  18. ESSENTIALLY CAKE BAKE+SKELETONS • Generators generate generators • Scaffolding similar

    to bake • Heavy community use • http://railswizard.org/ ^ Someone make this for CakePHP ^
  19. • Port of MerbAdmin • Ruby DSL Configuration • Similar

    to var $scaffold • Works with existing applications • Actively Developed, Unofficial https://github.com/sferik/rails_admin
  20. DJANGO PONY • Very customizable • Lots of available plugins

    • Lots of “themes” • Official Support
  21. WHY • Need custom admin interface on top of phpmyadmin

    • Can’t use Croogo/Infinitas/etc. • Need to replicate similar admin interfaces across projects • Let less technical developers create their own interfaces
  22. PHP-BASED CONFIGURATION class  CategoryCakeAdmin  extends  CakeAdmin  { /**  *  Where

     do  I  “scaffold”  this?  *  *  @var  string  */        public  $plugin                  =  'dashboard'; }
  23. BETTER BASE METHODS public  function  delete($id  =  null)  {  

         if  (!empty($this-­‐>data['Category']['id']))  {                if  ($this-­‐>Category-­‐>delete($this-­‐>data['Category']['id']))  {                        $this-­‐>Session-­‐>setFlash(__d('admin',  'Category  deleted',  true),  'flash/success');                        $this-­‐>redirect(array('action'  =>  'index'));                }                $this-­‐>Session-­‐>setFlash(__d('admin',  'Category  was  not  deleted',  true),  'flash/error');                $id  =  $this-­‐>data['Category']['id'];        }        $this-­‐>data  =  $this-­‐>Category-­‐>find('delete',  compact('id'));        if  (!$this-­‐>data)  {                $this-­‐>Session-­‐>setFlash(__d('admin',  'Category  unspecified',  true),  'flash/error');                $this-­‐>redirect(array('action'  =>  'index'));        } }
  24. CREATING NEW ACTIONS • Needs an *ActionConfig class • Templates

    for Controller/View - Model optional • Similar to Cake Bake Templates • Access to a model and the Admin class config
  25. WHATS IN AN ACTION <?php class  CakeAdminIndexConfig  extends  CakeAdminActionConfig  {

           //  Guess        var  $defaults  =  array(  /*  some  options  */);        //  Should  we  enable  this  by  default        var  $enabled  =  true;        //  Plugin  where  the  templates  for  this  action  are  located        var  $plugin  =  'cake_admin';        //  Action  type        var  $type  =  'index';        //  How  do  we  "link"  to  this  method        var  $linkable  =  'List  {{modelname}}';        //  Custom  model  methods  (find,  related)        var  $methods  =  array('find');        //  How  do  we  merge  our  defaults  and  configuration?        function  mergeVars($admin,  $configuration  =  array())  {        } }
  26. TODO • More actions (galleries, TreeBehavior) • Ajax and other

    UI enhancements • Web interface for customization • Scaffold-like interface in 2.0
  27. LINKS • CakeAdmin: http://github.com/josegonzalez/cake_admin • Baking Master Class: http://www.neilcrookes.com/2009/07/11/baking-master-class-cakefest-jul-09/ •

    AppSkellington: http://github.com/josegonzalez/app_skellington • Skel: http://github.com/ad7six/skel • Cake-Skel: https://github.com/jonbradley/cake-skel • BakingPlate: http://github.com/proloser/bakingplate • RailsAdmin: http://github.com/sferik/rails_admin • DjangoAdmin: https://docs.djangoproject.com/en/1.3/ref/contrib/admin/