{% extends '../base.html.twig' %}

{% block body %}
  <div class="container-fluid">
    <div class="row flex-xl-nowrap">
      {% include '../../documentation/navbar.html.twig' with {
        'route' : nodefony.route
      } %}
      <main class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5" style="top: 5rem;">
        <h1>Hello Word<h1>

        <h2>Generate hello Bundle :</h2>
        <h4>Command console to Generate new bundle :    <strong>generate:bundle name path</strong></h4>
        <br/>
        <br/>
        <pre><code class="hljs console" >$ <strong>nodefony generate:bundle hello src/bundles</strong>

        # Or Interactive Mode

        $ nodefony

        Wed Mar 27 2019 15:12:41 INFO nodefony : WELCOME PROJECT : nodefony-starter 1.0.0
        ?  Nodefony CLI :  Generater
        ?  Nodefony CLI :  (Use arrow keys)
        ❯ Generate New Bundle
          Generate New Controller
          Generate New Service
          Generate New Entity
          Generate New Nodefony Project
          Generate Openssl Certificates
          Generate Haproxy Configuration
          Generate Nginx Configuration
          Generate letsEncrypt Webroot Configuration
          --------
          Quit
               __ _    ___   _ __     ___   _ __    __ _  | |_    ___
              / _` |  / _ \ | '_ \   / _ \ | '__|  / _` | | __|  / _ \
             | (_| | |  __/ | | | | |  __/ | |    | (_| | | |_  |  __/
              \__, |  \___| |_| |_|  \___| |_|     \__,_|  \__|  \___|
              |___/


           Wed Mar 27 2019 15:13:33 INFO COMMAND : generate:bundle
          ? Generate Nodefony Bundle :  nodefony

        ? Enter Bundle Name hello
        ? Enter Bundle Path /Users/cci/repository/nodefony-starter/src/bundles
        ? Do You Want To Build Matrice C++ addon ? No
         Wed Mar 27 2019 15:13:51 INFO nodefony : GENERATE bundle : hello-bundle LOCATION : /Users/cci/repository/nodefony-starter/src/bundles
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :hello-bundle
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :controller
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :defaultController.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :Resources
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :config
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :config.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :routing.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :security.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :services.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :webpack.config.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :webpack
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :webpack.dev.config.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :webpack.prod.config.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :public
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :hello.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :css
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :hello.css
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :images
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :assets
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :css
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :fonts
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :images
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :translations
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :views
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :index.html.twig
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :tests
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :helloTest.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :Command
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :helloCommand.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :helloTask.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :services
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :doc
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :readme.md
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :helloBundle.js
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :readme.md
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :src
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :Entity
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :package.json
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create Directory :build
         Wed Mar 27 2019 15:13:51 INFO BUILDER : Create File      :.gitignore
         Wed Mar 27 2019 15:13:51 INFO nodefony : Spawn : npm install

        ...

        </code></pre>

        <p>
          <strong>Example files system after Generate Bundle :  </strong>
        </p>
        <pre><code class="hljs console" >$ ls -l src/bundles/hello-bundle

        drwxr-xr-x    4 cci  staff     128 27 mar 15:13 Command
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 Entity
        drwxr-xr-x    6 cci  staff     192 27 mar 15:13 Resources
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 build
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 controller
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 doc
        -rw-r--r--    1 cci  staff     642 27 mar 15:13 helloBundle.js
        drwxr-xr-x  646 cci  staff   20672 27 mar 15:14 node_modules
        -rw-r--r--    1 cci  staff  297699 27 mar 15:14 package-lock.json
        -rw-r--r--    1 cci  staff    1274 27 mar 15:14 package.json
        -rw-r--r--    1 cci  staff       1 27 mar 15:13 readme.md
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 services
        drwxr-xr-x    2 cci  staff      64 27 mar 15:13 src
        drwxr-xr-x    3 cci  staff      96 27 mar 15:13 tests

        </code></pre>

        <h2> AUTO REGISTRATION :</h2>
        <p>
          The bundle generation engine auto registre generated bundle in framework : <br>
          During the generation of a bundle nodefony uses a temporary yml file <strong>./config/generatedConfig.yml </strong><br>
        </p>

        <code>./config/generatedConfig.yml</code>
        <pre><code class="hljs yaml" >

        system:
          bundles:
            hello: src/bundles/hello-bundle
        </code></pre>
        <p>
          If the bundle is to be used in a durable way It is preferable to register the bundles in framework config file : <strong>  ./config/config.js</strong> <br>
        </p>
        <code>./config/config.js</code>
        <pre><code class="hljs javascript">module.exports = {

          /**
           *  BUNDLES LOCAL REGISTRATION
           *
           *       bundles:{
           *         hello-bundle : "file:src/bundles/hello-bundle"
           *       }
           *
           */
          bundles: {
            "hello-bundle": "file:src/bundles/hello-bundle"
          }

        }
        </code></pre>

        <h2> Generated VIEW :</h2>
        <code>src/bundles/hello-bundle/Resources/views/index.html.twig</code>

        <pre><code class="hljs twig">{% verbatim %}

        {% extends '/app/Resources/views/base.html.twig' %}

        {% block title %}Welcome {{name}}! {% endblock %}

        {% block stylesheets %}
          {{ parent() }}
          &lt;!-- WEBPACK BUNDLE --&gt;
          &lt;link rel='stylesheet' href="{{CDN("stylesheet")}}/hello-bundle/assets/css/hello.css" /&gt;
        {% endblock %}

        {% block body %}
          {% block header %}
            {{ render( controller('app:app:header' )) }}
          {% endblock %}

          &lt;div class='container' style='margin-top:100px'&gt;
            &lt;div class='row'&gt;
              &lt;div class='col text-center'&gt;
                &lt;img src="{{CDN("image")}}/app/images/app-logo.png"&gt;
                &lt;a href='#'&gt;
                  &lt;strong style='font-size:45px'&gt;{{name}}&lt;/strong&gt;
                &lt;/a&gt;
                &lt;p class='display-4 mt-5'&gt;{{trans('welcome')}}&lt;/p&gt;
                &lt;p&gt;{{binding}}&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;

          {% block footer %}
            {{ render( controller('app:app:footer' )) }}
          {% endblock %}
        {% endblock %}

        {% block javascripts %}
          {{ parent() }}
          &lt;!-- WEBPACK BUNDLE --&gt;
          &lt;script src="{{CDN("javascript")}}/hello-bundle/assets/js/hello.js"&gt;&lt;/script&gt;
        {% endblock %}
        {% endverbatim %}
        </code></pre>
        <h2> Generated Controller :</h2>
        <code>src/bundles/hello-bundle/controller/defaultController.js</code>
        <pre><code class="hljs javascript">/**
         *	@class defaultController
         *	@constructor
         *	@param {class} container
         *	@param {class} context
         *
         */
        module.exports = class defaultController extends nodefony.controller {

          constructor (container, context){
            super(container, context);
          }

          /**
           *
           *	@method indexAction
           *
           */
          indexAction (){

            return this.render("hello-bundle::index.html.twig", {
              name: "hello-bundle"
            }).catch((e) =>{
                throw e ;
            });

          }
        };
        </code></pre>

        <h2> WATCHER FILES DURING DEVELOPMENT :</h2>
        <p>
        The bundle generation engine build bundle config with  node.js watcher configuration <br>
        In developement mode  is very usefull to auto-reload files as controllers , views , routing , translations <br>
        without having to reboot the server.
        </p>
        <code>./src/bundles/hello-bundle/Resources/config/config.js</code>
        <pre><code class="hljs javascript">module.exports = {

          /**
           *    WATCHERS
           *
           *  watchers Listen to changes, deletion, renaming of files and directories
           *  of different components
           *
           *  For watch all components
           *      watch:                    true
           *  or
           *      watch:{
           *        controller:             true,
           *        config:                 true,        // only  routing.js
           *        views:                  true,
           *        translations:           true,
           *        webpack:                true
           *      }
           *
           */
          watch: true

        };
        </code></pre>

        <h2> WEBPACK MODULE BUNDLER :</h2>
        <p>
        The bundle generation engine build bundle config with a predefined webpack configurations <br>
        In this way webpack is very usefull to manage all assets of bundle <br>
        In developement mode watch is very usefull to auto-compile webpack module bundle <br>
        without having to reboot the server.
        </p>

        <code>./src/bundles/hello-bundle/Resources/config/webpack.config.js</code>
        <pre><code class="hljs javascript">const path = require("path");
        //const webpack = require('webpack');
        const MiniCssExtractPlugin = require("mini-css-extract-plugin");
        const webpackMerge = require('webpack-merge');

        // Default context <bundle base directory>
        //const context = path.resolve(__dirname, "..", "Resources", "public");
        const public = path.resolve(__dirname, "..", "public", "assets");
        const bundleName = path.basename(path.resolve(__dirname, "..", ".."));
        const publicPath = bundleName + "/assets/";

        let config = null;
        let dev = true;
        if (kernel.environment === "dev") {
          config = require("./webpack/webpack.dev.config.js");
        } else {
          config = require("./webpack/webpack.prod.config.js");
          dev = false;
        }

        module.exports = webpackMerge(config, {
          //context: context,
          target: "web",
          entry: {
            hello  : [ "./Resources/public/js/hello.js" ]
          },
          output: {
            path: public,
            publicPath: publicPath,
            filename: "./js/[name].js",
            library: "[name]",
            libraryExport: "default"
          },
          externals: {},
          resolve: {},
          module: {
            rules: [{
                // BABEL TRANSCODE
                test: new RegExp("\.es6$|\.js$"),
                exclude: new RegExp("node_modules"),
                use: [{
                  loader: 'babel-loader',
                  options: {
                    presets: ['@babel/preset-env']
                  }
                }]
              },
              /*
               *	JQUERY EXPOSE BROWSER CONTEXT
               *
               */
              {
                test: require.resolve("jquery"),
                loader: "expose-loader?$!expose-loader?jQuery"
              }, {
                test: /jquery\..*\.js/,
                loader: "imports-loader?$=jquery,jQuery=jquery,this=>window"
              }, {
                test: /\.(sa|sc|c)ss$/,
                use: [
                  //'css-hot-loader',
                  MiniCssExtractPlugin.loader,
                  {
                    loader: "css-loader",
                    options: {
                      sourceMap: true
                    }
                  }, {
                    loader: 'resolve-url-loader',
                    options: {}
                  }, {
                    loader: 'postcss-loader', // Run post css actions
                    options: {
                      plugins: () => [require('precss'), require('autoprefixer')]
                    }
                  }, {
                    loader: "sass-loader",
                    options: {
                      sourceMap: true
                    }
                  }
                ]
              }, {
                test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
                use: [{
                  loader: 'file-loader',
                  options: {
                    name: '[name].[ext]',
                    outputPath: 'fonts/', // where the fonts will go
                    publicPath: `/${bundleName}/assets/fonts/` // override the default path
                  }
                }]
              }, {
                // IMAGES
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                  loader: "file-loader",
                  options: {
                    name: "[name].[ext]",
                    publicPath: `/${bundleName}/assets/images/`,
                    outputPath: "/images/"
                  }
                }]
              }
            ]
          },
          plugins: [
            new MiniCssExtractPlugin({
              filename: "./css/[name].css",
              allChunks: true
            })
          ],
          devServer: {
            inline: true,
            hot: false
          }
        });

        </code></pre>

        <code>./src/bundles/hello-bundle/Resources/config/webpack/webpack.dev.config.js</code>
        <pre><code class="hljs javascript">const CleanWebpackPlugin = require('clean-webpack-plugin');
        //const public = path.resolve(__dirname, "..", "..", "public");

        module.exports = {
          mode: "development",
          devtool: "source-map",
          resolve: {},
          plugins: [
            new CleanWebpackPlugin({
              verbose: kernel.debug
            })
            //new webpack.NamedModulesPlugin(),
            //new webpack.HotModuleReplacementPlugin()
          ]
        };
        </code></pre>


        <h2> Start Nodefony to check new Bundle hello:</h2> -d for debug mode
        <pre><code class="hljs console">$ nodefony -d dev
         or
        $ nodefony dev
        </code></pre>

        Access to bundle route with URL : http://mydomain.com:5151/hello

      </main>
    </div>
  </div>
{% endblock %}
