Les Bundles – que vous allez regretter de ne pas avoir connu plus tôt – GenemuFormBundle



Les Bundles – que vous allez regretter de ne pas avoir connu plus tôt – GenemuFormBundle

2 8


best-bundle-conf

Symfony Live Paris 2013 talk about the best and unknown Symfony2 Bundles (in French)

On Github jolicode / best-bundle-conf

Les Bundles

que vous allez regretter de ne pas avoir connu plus tôt

Une présentation par Damien Alexandre / JoliCode Symfony Live Paris 2013

@damienalexandre

Conseil, réalisation, audit, expertise et formation

...Poney, Guinness et gif animés.

Le menu

Qu'est-ce qu'un « Bundle » Les Bundles que même ta mamie connaît ♥ Les Bundles à aimer ♥ Comment choisir un Bundle ?

Qu'est-ce qu'un Bundle ?

Everything !

Symfony2 est lui même un Bundle !

Pensez à doctrine-bundle, sensio/distribution-bundle, sensio/framework-extra-bundle, sensio/generator-bundle

cache:clear et assets:install, c'est pas dans Symfony mais dans Distribution Bundle

Pourquoi c'est génial

  • Des Contrôleurs
  • Des Commandes
  • Des Services
  • Des Entités / Documents
  • Des Assets (js, css, images)
  • Des Dépendances (librairies)
  • Des Outils de debug
  • REDISTRIBUABLE & AUTONOME

Quelques chiffres

  • 1952 Bundles*
  • Plus d'1,5 Bundle par jour est publié
  • Symfony 1 ne compte que 1445 plugins

* source : knpbundles.com (on en trouve 1667 sur packagist et 988 sur symfohub)

Si on compte les jours depuis la premières version publique de SF2 en fev. 2010

On est encore loin...

  • des 24 000 plugins Wordpress
  • des 21 000 modules Drupal
  • des 6 141 extensions Joomla!
  • des 5 706 extensions Typo3

Et d'un côté : tant mieux...

il y aurait 1600 plugins RoR et 1688 packages Django.

Les Bundles que même ta mamie connaît

FOSUserBundle

  • Gestion des utilisateurs
  • Stockage Doctrine ou ODM ou Propel
  • Formulaire d'inscription
  • Mot de passe oublié
  • ...

FOSRestBundle

  • Création d'API REST à la volée
  • Un contrôleur pour plein de formats de sortie
  • Génération de routes automatiques
  • Négociation du format (accept)
    <?php
    class PoniesController
    {
        public function getPoniesAction()
        {} // "get_ponies"     [GET] /ponies

        public function newPoniesAction()
        {} // "new_ponies"     [GET] /ponies/new

StofDoctrineExtension‐Bundle

  • Installe et configure 11 extensions Doctrine2
  • l3pp4rd / DoctrineExtensions
    /**
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(type="datetime")
     */
    private $created;

    /**
     * @Gedmo\Blameable(on="create")
     * @ORM\Column(type="string")
     */
    private $createdBy;

Cité dans la doc officielle

♥ FOS : Friends of Symfony ♥

Les meilleurs Bundles sous la responsabilité des contributeurs les plus motivés et compétents.

http://friendsofsymfony.github.com/

♥ FOS ♥

  • FOSCommentBundle
  • FOSOAuthServerBundle
  • FOSMessageBundle
  • FOSFacebookBundle
  • FOSTwitterBundle
  • FOSJsRoutingBundle
  • FOS Elastica ajouté la semaine dernière

Vespolina

http://try.vespolina.org/ 24 Bundles orientés e-commerce

Sonata Bundles

http://sonata-project.org/

Par Thomas Rabaix ici présent (a donné une conf hier). Sonata c'est aussi des Bundles de gestion de Media, de Cache, de Block... La description dit "e-commerce" mais il n'en est rien. (20 bundles)

Sylius

http://sylius.org/

23 bundles pour une solution e-commerce inspirée par Spree (Ruby)

Les Bundles à aimer

Pour le développeur efficace

Qui a dit « fainéant » ?

GenemuFormBundle

Select2

reCAPTCHA

TinyMCE

Datepicker, Slider, Autocomplete, Colorpicker, Rating, File...

Un super form theme

{% block genemu_jqueryrating_javascript %}
{% spaceless %}
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            $('[name="{{ full_name }}"]').rating({{ configs|json_encode|raw }});
        });
    </script>
{% endspaceless %}
{% endblock genemu_jqueryrating_javascript %}

Facile à installer

  • Librairies JS à maintenir vous même
  • S'utilise comme n'importe quel FormType
<?php
// ...
public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('captcha', 'genemu_recaptcha');
}

BazingaFakerBundle

agit en remplacement ou complément des fixtures après tout, il expose Faker en tant que service

Faker

echo $faker->name;
  // 'Lucy Cechtelar';
echo $faker->address;
  // "426 Jordy Lodge
  // Cartwrightshire, SC 88120-6700"
echo $faker->text;
  // Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam excepturi
  // beatae sint laudantium consequatur. Magni occaecati itaque sint et sit tempore. Nesciunt
  // amet quidem. Iusto deleniti cum autem ad quia aperiam.
  // A consectetur quos aliquam. In iste aliquid et aut similique suscipit.

Intégration via Yml

bazinga_faker:
    entities:
        Joli\PonyBundle\Model\Pony:
            number: 5
        Joli\PonyBundle\Model\Guinness:
            number: 55

Features

  • Formateurs custom
  • Supporte Propel & Doctrine & Mandango
  • php app/console faker:populate

IgorwFileServeBundle

On peut servir des fichiers sans les mettre dans /web !

Support de Sendfile

  • Envoi de gros fichiers sans passer par PHP
  • Délégation complète au serveur HTTP
    • Nginx XSendfile
    • Apache mod_xsendfile

Utiliser SendFIle c'est juste un header HTTP

BinaryFileResponse

  • En discussion depuis plus d'un an
  • Mergé il y a 3 mois en 2.2
  • Documenté depuis hier !*

* symfony/symfony-docs/pull/2416

BinaryFileResponse

  • Supporte SendFile
  • Supporte If-Range
  • X-Accel-Mapping
  • Envoi via PHP par défaut

BinaryFileResponse

use Symfony\Component\HttpFoundation\BinaryFileResponse

$file = '/var/private/r-black-Friday-Friday.mp4';
$response = new BinaryFileResponse($file);
$response::trustXSendfileTypeHeader();

NelmioApiDocBundle

(ouais je sais Guillaume en a parlé hier)

Interface basée sur Swagger-UI introspection et annotation pour avoir une doc toujours à jour

Annotations

<?php
class PonyController extends Controller
{
    /**
     * Ce blabla sera dans la documentation :)
     *
     * @Route("/pony")
     * @Method({"GET"})
     * @ApiDoc(
     *  resource=true,
     *  description="Obtenir des poneys",
     *  filters={
     *      {"name"="color", "dataType"="integer"}
     *  }
     * )
     */
    public function getAction() { }

Possibilité d'export statique

app/console api:doc:dump --format=html > api.html

Markdown, HTML, Json

Pour profiler et inspecter

Performance et statistiques sont nos amis

LswMemcacheBundle

* (Attention quand même)

Memcache quand il a plus de place, il... SUPPRIME.

Bundle tout réçent

Un service pour Memcached

lsw_memcache:
    clients:
        default:
            hosts:
              - { dsn: localhost, port: 11211 }
$this->get('memcache.default')->set('Ponies', 'Are Awesome', 1111);
$this->get('memcache.default')->get('Ponies');

Grandement configurable (toutes les options de memcached)

Sessions en mémoire

lsw_memcache:
    session:
        client: default
  • Aucun accès disque
  • Pas de stockage en base de données
  • Scalable
  • La RAM c'est pas cher, mangez-en

Intégration Web Debug Toolbar

Intégration Web Debug Toolbar

ADP

$this->get('memcache.default')->setAdp('Ponies', 'Yolo', 1111);
$this->get('memcache.default')->getAdp('Ponies');
  • Sert l'ancienne valeur après expiration
  • Seulement 1 process obtient un cache MISS
  • Plus lent

JSMysqlndBundle

MySQL Native Driver:

  • Optimisé, meilleur que libmysql
  • Utilise le coeur de PHP en C
  • PHP memory management
  • Plugins

Notez que c'est JS, pas JMS, ce n'est pas le johannes que l'on connait

Statistiques

Statistiques QC

Avec un plugin mysql ND, nommé Query Cache, on a une stack trace possible.

Le truc sert à faire du cache de query/result applicatif, mieux que celui de Doctrine.

Marche avec APC, Memcache...

En savoir plus

WebProfilerExtraBundle

Web Debug Toolbar

LE NOM DU TEMPLATE YEAH. Le reste on s'en fout. Manque les includes, les extends... a creuser !

Variables Twig

Router

ZenstruckCacheBundle

Sitemap

zenstruck_cache:
    sitemap_provider:     true
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>http://local.sf2-bundles.com/</loc></url>
  <url><loc>http://local.sf2-bundles.com/registration/</loc></url>
  <url><loc>http://local.sf2-bundles.com/demo/</loc></url>
  <url><loc>http://local.sf2-bundles.com/demo/hello/World</loc></url>
  <url><loc>http://local.sf2-bundles.com/demo/hello/Coucou</loc></url>
  <url><loc>http://local.sf2-bundles.com/demo/hello/Poney</loc></url>
</urlset>

Bonus : Un Bundle pour générer votre sitemap !

Via un service

awesome_url_provider:
    class: Acme\DemoBundle\HttpCache\AwesomeWarmupProvider
    tags:
        - { name: zenstruck_cache.url_provider }
<?php
use Zenstruck\Bundle\CacheBundle\HttpCache\UrlProviderInterface;

class AwesomeWarmupProvider implements UrlProviderInterface
{
   public function getUrls($host = null)
   {
       $urls = array();

       // do ur biznessss

       return $urls;
   }
}

Ligne de commande

app/console zenstruck:http-cache:warmup http://local.sf2-bundles.com

4/5 [======================>-----] 80%
SHINNY PROGRESS BAR!!

NelmioJsLoggerBundle

Remplace « onerror »

{{ nelmio_js_error_logger() }}
(function() {
    var oldErrorHandler = window.onerror;
    window.onerror = function(errorMsg, file, line) {
        if (oldErrorHandler) {
            oldErrorHandler(errorMsg, file, line);
        }
        (new Image()).src = '/nelmio-js-logger/log?msg='; // [...]
    };
})();
Bien sûr la route est configurable dans le routing

Une erreur et c'est le drame

Sans NelmioJsLoggerBundle, elle serait perdue à jamais :(

Dans nos logs

[2013-03-23 19:38:20] event.DEBUG: blablabla
[2013-03-23 19:38:20] event.DEBUG: blablabla
[2013-03-23 19:38:20] frontend.ERROR: Uncaught ReferenceError: loadCornify is not defined {"file":"http://local.sf2-bundles.com/app_dev.php/demo/hello/World","line":"50","browser":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22","page":"http://local.sf2-bundles.com/app_dev.php/demo/hello/World"} []
[2013-03-23 19:38:20] event.DEBUG: blablabla

Vos propres logs

{{ nelmio_js_logger() }} {# Expose une fonction log() #}

Et pourquoi ne pas remplacer aussi console.log() !

JnsXhprofBundle

Activation facile

jns_xhprof:
    location_lib:    "/usr/share/php5-xhprof/xhprof_lib/utils/xhprof_lib.php"
    location_runs:   "/usr/share/php5-xhprof/xhprof_lib/utils/xhprof_runs.php"
    location_config: "/usr/share/php5-xhprof/xhprof_lib/config.php"
    location_web:    "http://127.0.0.1/xhprof/"
    enabled:         true

Dans la web debug toolbar

Ça c'est l'interface du paquet par défaut, et c'est moche.

Callgraph par defaut

Support de XHGui

Sexy je vous dit

Pour améliorer le Front

On est tous un peu intégrateur

./symfony project:disable

LexikMaintenanceBundle

lexik_maintenance:
    authorized_ips: ['127.0.0.1']
    driver:
        ttl: 3600
        class: '\Lexik\Bundle\MaintenanceBundle\Drivers\FileDriver'
        options:
            file_path: '%kernel.root_dir%/cache/lock'

Une commande

./app/console lexik:maintenance:lock

Se customise comme les autres : error503.html.twig.

BazingaExpose‐TranslationBundle

Translator & vos chaînes

{{ url('bazinga_exposetranslation_js') }}
<script type="text/javascript"
    src="/bundles/bazingaexposetranslation/js/translator.min.js">
</script>
<script type="text/javascript"
    src="http://local.sf2-bundles.com/app_dev.php/i18n/messages/en">
</script>
Translator.locale = 'en';
Translator.defaultDomains = ["messages"];
Translator.add("messages:homepage.pony", "I fucking love ponies");
Translator.add("messages:symfony2.great", "I love Symfony2");

Translator

  • Logique de pluriels de Symfony2
  • Testé unitairement
  • Détection de Domain (explore tous les catalogues avant de retourner null)
Translator.has('messages:homepage.pony');
>> true
Translator.get('messages:homepage.pony');
>> "I fucking love ponies"
Translator.get('messages:homepage.pony.unknown');
>> "messages:homepage.pony.unknown"
Translator.locale
>> "en"

Les mêmes traductions au front et au back \o/

VOus pouvez n'exposer qu'un catalogue (faire un catalogue "js" par exemple).

APYJsFormValidation‐Bundle

Contrainte du Validator

/**
 * @var string
 *
 * @Assert\MinLength(
 *     limit=3,
 *     message="Your pony name is not verbose enough!"
 * )
 * @Assert\NotBlank()
 * @ORM\Column(name="name", type="string", length=255)
 */
private $name;

Affichage du formulaire

{{ JSFV(form) }}
<script type="text/javascript" src="/bundles/jsformvalidation/js/_demo_hello_form.js"></script>

_demo_hello_form.js = Nom de la route + Nom du Form

Un Javascript par formulaire

check_form_name: function() {
    var gv;
    result = true;
    result = result && checkError('form_name', MinLength, {message:"Your pony name is not verbose enough!", limit:3, charset:"UTF-8"} );
    result = result && checkError('form_name', NotBlank, {message:"This value should not be blank."} );
    return result;
},

Validation en Javascript

<div>
    <label for="form_name" class="required">Name</label>

    <ul class="error_list">
        <li>Your pony name is not verbose enough!</li>
    </ul>

    <input type="text" id="form_name" name="form[name]" required="required">
</div>
Il va chercher les traductions dans la clé "validators" par défaut

Pour le fun

Carambar® is coming

Une documentation en Japonais

What could possibly go wrong...

SymfonyanBundle

Ça marche pas

$ app/console symfonyan:exception-install
Installing symfonyan exception to app/Resources/FrameworkBundle

Destination fausse, vues 2.0... mais on corrige !

Nouvelle page d'erreur

Nouvelle exception

Page de bienvenue

$ app/console symfonyan:welcome-install
Installing symfonyan welcomepage to app/Resources/AcmeDemoBundle

sfContextBundle

Quick & Dirty YEAH

$request = \sfContext::getInstance()->getContainer()->get('request');

Problème de scope / dépendance ? Plus jamais !

\sfContext::createInstance($this->container);

\sfContext::getInstance();

NON

MarcWWurstBundle

SAUCISSE

$ app/console wurst:print
Art from: http://www.wurstblog.de/aufschnitt/ascii-wurst
                                                                                      .c.
                                                                                     .0MXd'
                                                                                    ,KMMMMWO:.
                                                                                   :NMMMMMMMMXo.
                                                                   .,:cllllc:,..  lWMMMMMMMMMMMWk;
                                                             .,cd0NWMMMMMMMMMMWN00WMMMMMMMMMMMMMMMKo.
                                                          .ckXMMMMMMMMMMMMMMMMMMMMMMMMWNXK00Okxdolc:,
                                                       'l0WMMMMMMMMMMMMMMMMMMMMMMMMMMMNo.
                                                    .l0WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWo
                                                 .cOWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN'
                                               'dXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMX.
                                             ;OWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMX;
                                          .lKWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMW0l.
                                        .oNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXkc.
                                       ;KMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKd;.
                                     .xWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXd,
                                    '0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWO:.
                                   ;XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNx'
                                  :NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWk'
                                 ;NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMK;
                                .XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWk.
                                kMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWd
                               ;WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMx
                               kMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWk.
                              .XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0.
                              ;WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMo
                              ;WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMl
                              ,NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd
                              .XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM0.
                               xMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWk.
                               ;WMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd
                                kMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWl
                                'XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWo
                                 :NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWk.
                                  cWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMK;
                                   :XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWl
                                    .0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN'
                                     .xWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMK.
                                       :XMMMMMMMMMMMMMMMMMMMMMMMMMMMMK,
                                        .dNMMMMMMMMMMMMMMMMMMMMMMMMKl.
                                          .ckXWMMMMMMMMMMMMMMMMMXd,
                                              ':lxkO0KK00WMMMMMMN0xl;.
                                                        .KMMMMMMMMMMMWXOd:'.
                                                        .0MMMMMMMMMMMMMMMN0o'
                                                         OMMMMMMMMMMN0xc,.
                                                         OMMMMWX0dc'.
                                                         xKkl;.
                                                         ..
                        

Beaucoup d'options

Usage:
wurst:print [--mit-pommes] [--mit-mayonnaise] [--mit-beer] [--mit-pretzel] [--mit-coffee] [--mit-kase] [--mit-chocolate] [--mit-wine] [--mit-tea] [--mit-ketchup] [--mit-aioli] [--mit-tomato] [type]

Arguments:
type                  Which type of würst you want (blackpudding, wiener, salami, running-wurst, bratwurst_mit_broetchen, classic, schwarzwurst, landjaeger, veggie, choux, chorizo, gerauchertewurst, mettwurst, botifarra_mit_mongetes, currywurst, grill-servelat, wurst_morteau_fr, vegan, weisswurst, im_schlafrock, hotdog)? (default: "classic")
app/console wurst:print im_schlafrock --mit-beer

                                          .,:;::;;;:,
                                  .::rS2XX25i2223&G&H&Xh35r,.
                                ;53MB32Si525iSisri5hAh222XAG&35;.
                              rh&h225iiisrrr;5iSs;r2SrS2SsS5S2X3h5rr:
                          ii.;ii52i5iiSiiir;ri55Sr:;rrrsrsSS2222XX&A22Xr;..
                        :#@::X2;srri5rrriSirsrrrrrr;sr;rrsss5si3X5ii;rS9A3X5ir;,.
                        &@r,AAXSsSi;sisrrr;;rr;;;:;ssssrrr;rr;rsSSSSrs;;rs3X9hHhHA2:
                        #@,;A2i522r:;riisssirrsrrr;;;;r;;;:,rsXi52Xir;:r;r52X32;;sA@H.
                        9@3 .;rrrrsr;,:;rrsiS;:rr:;r:;r;r;;;rrr;5ii;;;ir;;rrsi55isssX&s.
                        i&@#r:. .,;iir:;rr;;rr;,:;r;;::;;;r;;;:,,s,:,;sS,:s:rrss232SS9AAGr
                        ,5@@@@@@9::ssrrrsr;s;:r::;;;::,:rr;;;,,;;, ,,rriir:,:;rii2XissrrSXirr
                          ;ii2iXhr::,;rsr;;rr;;;.:, :r:,;,:;,,:;;..:s,:S5r::rrisi;.;ir;rrsS52XS:.
                           .2HHHM@@B9552srsr.,..,,,:.,,. .:,..,;;:::,,sisir.;is:s.,i5522S5X9&H##A9s.
                             ;XH#@@@@@@@@@@Hr,. ..,:,,,.,:..  :::;,..::,;rr,ss,,s;r;rSSSiiiSiri3hM#B5
                                    ,;i9H#@@@@@@&i:.. ,;::,.,,,:;..:,;,.:ii:rs r;s;:rSiiissr;:s23AX52i;
                                            :ih#@@@HS:  .:..:..;s::i::::rX2;;;;rrs:;:rrs32S2S55siX9##G22;
                                                 ,S#@@3, ,, ...,;;,;:;r:r;;r,.:;rSrrr5255S29522riXAM##AABBr
                                                     ;@@3;   ,:,;;r,:r;,,.;:.,;sr;:i3iSXrsssi2X32sSAG32MBB##
                                                       SB#&;  ::;r;.;,,r:.: ,::;::;ssiS;rs2BMGAh3ii&9G9M&MH@&
                                                         .r2S,. ;. :r.:r,.,.,,::;rSs:sir;r9GA#HGhGXX2XXXSi2G@:
                                                            ,;;...:r;. ..,.,,,,:;sr.:iiiSsihHGSrr22s;;;;;;r5BS
                                                              .::;;:   ....,,.,:;;:;rrrrr;XG5isr,:;:.,,,,:;S#H
                                                                 ,;2X;..,....,;;:,;;.;;;rr2Sr;,...,Ss;r;. .,9:
                                                                    r&&i;, ..,,:.,..:r:irSi;  ,rr:r&S:,.... ,
                                                                      .2#Hr.   ,,,.:rrisi;,:rG@#Ah2XMi..,.  ;:
                                                                         i@M2. ,:,,;risr,.h@@@@#XSiri3r,....,.
                                                                           s#A,.,:,,:rS; A@@@##A;:hsiShr,...
                                                                             i5,,;:::rr,;@@#HHBhrrX;iS2Gr,.
                                                                              :rr,:;;;r,;##H#@MA3r:rS252i:,
                                                                               .,,.;;:;;;2hH@@#AAX399h2s;:
                                                                                 ..,;;;;:;SXhBG9A9GhXs:.;.
                                                                                     .:;r;:rsrS52Si;,,,,
                                                                                        :SXXA2S5X5i2s:.
                                                                                           :ssrrr;:r.

                                 _.._..,_,_
                                (          )
                                 ]~,"-.-~~[
                               .=])' (;  ([
                               | ]:: '    [
                               '=]): .)  ([
                                 |:: '    |
                                  ~~----~~

                        from : http://www.ascii-art.de/ascii/ab/beer.txt

EasterEggBundle ?

Si vous ne savez pas quoi faire demain au Hacking Day !

Comment choisir un Bundle ?

Comment choisir le meilleur Bundle de Bootstrap, le meilleur Blog Bundle...

Des sites spécialisés

Score & popularité

  • 1 point par follower sur GitHub
  • 5 points pour un bon README (300 caractères)
  • 5 points pour Travis CI
  • 5 points si Travis CI est vert
  • 5 points si Composer
  • 5 points par recommandation KnpBundles
  • Petit boost sur les commits récents

Score & popularité

  • Nombre d'installations / jour
  • Nombre de dépendances
  • Nombre de versions

Qualité

https://scrutinizer-ci.com

SensioLabs Insight aussi, peut-être...

Maintenance

The end

throw $questions;

http://jolicode.github.com/best-bundle-conf/

coucou@jolicode.com