SlideShare a Scribd company logo
DÉVELOPPEREN
JAVASCRIPT:
UNEEXTENSIONDEAÀZ
WORDCAMPPARIS2015
QUISUIS-JE?
Développeur PHP et JavaScript
Développeur avec WordPress depuis 5 ans
Développeur à @bea_api
ÉVOLUTIONDU
JAVASCRIPT
ÉVOLUTIONDE
WORDPRESS
LESOUTILS
COMMENTLESUTILISER?
Automatisation
NodeJS
NPM
Gulp ou Grunt
Plugins, JSHint, Sourcemap, Concat, Minify...
LESSOLUTIONSDANS
WORDPRESS
Backbone
Underscore
Modèles, vues, collections, routes, async, sync etc.
Deux plugins
LEPETITPLUGIN
ACF
Enfin juste l'admin
simplifiée
Développer en javascript une extension de A a Z
STRUCTUREDEL'APP
Structure de base en PHP
Ajouter la page admin
Gestion de l'enregistrement
             
<!­­ Create a header in the default WordPress 'wrap' container ­­>
<div class="wrap">
  <!­­?php
  // Get the current screen
  $screen = get_current_screen();
  settings_errors( 'wc­acf' );
  ?­­>
  <h2><!­­?php echo get_admin_page_title() ?­­></h2>
  <form method="POST" id="wc­acf­edit" action="<?php echo admin_url( 'admin
    <div class="wc_acf_fields widefat postbox">
      <div class="no_fields_message">Aucun champs. Cliquez sur 
      <div class="fields"></div>
      <div class="wc_acf_add_wrapper">
        <!­­?php submit_button( 'Ajouter +', 'primary', '
      </div>
    </div>
    <!­­?php wp_nonce_field( 'wc­acf­edit' ); ?­­>
    <!­­?php submit_button(); ?­­>
    <input type="hidden" name="wc_acf_save_fields" value="1">
    <input type="hidden" name="redirect_to" value="<?php echo add_que
    <input type="hidden" name="action" value="wc_acf_save">
  </form>
</div>
<!­­ /.wrap ­­>
           
STRUCTUREDEL'APP
Structure pour le reste
METTREENPLACEL'ENVIRONNEMENT
package.json
{
  "name": "wc­acf",
  "version": "1.0.0",
  "description": "WC ACF",
  "author": "Nicolas Juen",
  "devDependencies": {
    "gulp": "^3.8.1",
    "gulp­concat­sourcemap": "~1.3.1",
    "gulp­cssmin": "^0.1.6",
    "gulp­jshint": "~1.9.0",
    "gulp­load­plugins": "^0.5.2",
    "gulp­rename": "^1.2.0",
    "gulp­uglify": "~0.2.1",
    "gulp­watch": "~0.6.8",
    "matchdep": "*"
  }
}
npm install --save-dev gulp-rename
NPMINSTALL
attendre...
attendre...
Fini !
Enfin tout va dépendre de votre connexion internet ;)
GULP
Gestionnaire de tâches
Deux tâches
L'importance de watch
GULP
gulp.task('dev', function () {
  return gulp.src([
    'assets/js/src/main.js',
    'assets/js/src/tools.js',
    'assets/js/src/vendor/*.js',
    'assets/js/src/tools/*.js',
    'assets/js/src/views/*.js',
    'assets/js/src/models/*.js',
    'assets/js/src/routers/*.js',
    'assets/js/src/controllers/*.js',
    'assets/js/src/init.js'
    ])
    .pipe(plugins.jshint())
    .pipe(concat('app.js', { sourceRoot : '../../' }))
    .pipe(gulp.dest('assets/js/'));
});
WATCH!
"On me dit de carreler, je carrèle, on me
dit de pas carreler j’carrèle pas."
// On default task, just compile on demand
gulp.task('default', function() {
  gulp.watch('/assets/js/*.js', [ 'dev' ]);
});
LEMODÈLE
/**
 * Field model
 */
'use strict';
fr.wc_acf.models.Field = Backbone.Model.extend({
    defaults: {
        type : 'text',
        title : '',
        name : '',
        settings : '',
        description : ''
    }
});
Get
Set
...
LESVUES
Gestion de ses petites affaires
template
el
$el
this
3VUES
Principale
Champs
Paramètres
VUEPRINCIPALE
Events
Affichage (render)
events :{
      'click #wc_acf_add_field' : 'add'
    },
VUEPRINCIPALE
append_item : function( data ) {
        'use strict';
        var self = this,
            model = new fr.wc_acf.models.Field( data ),
            item_view = new fr.wc_acf.views.Field( {
                model : model
            } );
        self.counter++;
        var rendered = item_view.render( ).$el;
        self.$el.find( '.wc_acf_fields .fields' ).append( rendered );
        rendered.find( 'input:first').focus();
        // Update the fields
        this.on_empty_fields();
    },
VUECHAMPS
Events
Affichage (render)
events : {
        'click .wc_acf_delete' : 'delete',
        'change .wc_acf_type' : 'change_type',
        'keyup .wc_acf_title' : 'update_title',
        'keyup .wc_acf_name' : 'update_name',
        'blur .wc_acf_title' : 'clear_name',
        'keyup .wc_acf_description' : 'update_description',
        'keyup .wc_acf_settings' : 'update_settings'
    },
LERENDUD'UNEVUE
render : function() {
        this.settings = new fr.wc_acf.views.Settings( {
            model : this.model
        });
        this.$el.html( this.template( {
            id : this.model.get('id'),
            type : this.model.get( 'type' ),
            title : this.model.get( 'title' ),
            name : this.model.get( 'name' ),
            settings : this.model.get( 'settings' ),
            description : this.model.get( 'description' ),
            html_field: this.settings.render().$el.html()
        } ) );
        this.stickit();
        return this;
    },
VUECHAMPS
data-binding : Stick.it
Lier le modèle et la vue
bindings: {
        '.wc_acf_title_label .title': {
            observe: 'title',
            onGet: function(title) {
                return title || 'Nouveau champ';
            }
        },
        '.wc_acf_name': {
            attributes: [{
                name: 'value',
                observe: 'name'
            }]
        }
    },
VUESETTINGS
Gère un template optionnel
C'est la vue du champs qui va gérer ce champs
supplémentaire
RENDRELESDONNÉES
ENREGISTRÉES
fr.wc_acf.main_view = new fr.wc_acf.views.Main();
// Fill the view
if( !_.isUndefined( wc_acf_vars.fields_data ) ) {
    _.each( wc_acf_vars.fields_data , function(field) {
        fr.wc_acf.main_view.append_item(field);
    } );
}
FAIRECOMMUNIQUER
TOUTLEMONDE
jQuery.trigger
Mediator
Publish
Subscribe
SubscribeOnce
PARTOUTDANSLECODE
subscriptions: {
        'field:remove': 'field_remove'
    },
Backbone.Mediator.publish( 'field:remove' );
LESTEMPLATESTAG
UNDERSCORE
Afficher les variables, executer du Javascript
<%= variable %>
Memoize les templates
wp-includes/js/wp-util.js L17
wp.template = _.memoize(function ( id ) {
var compiled,
  /*
   * Underscore's default ERB­style templates are incompatible with PHP
   * when asp_tags is enabled, so WordPress uses Mustache­inspired templati
   *
   * @see trac ticket #22344.
   */
  options = {
    evaluate:    /<#([sS]+?)#>/g,
    interpolate: /{{{([sS]+?)}}}/g,
    escape:      /{{([^}]+?)}}(?!})/g,
    variable:    'data'
  };
return function ( data ) {
  compiled = compiled || _.template( $( '#tmpl­' + id ).html(), null, optio
  return compiled( data );
};
LECODE
https://github.com/Rahe/wc-acf
ou
http://goo.gl/kKjfuZ
CONCLUSION
- - - WordCamp Paris 2015Nicolas JUEN @Raherian @be_api
ETVOUS?
Merci

More Related Content

Développer en javascript une extension de A a Z