PHP code example of finalclass / nbml

1. Go to this page and download the library: Download finalclass/nbml library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

finalclass / nbml example snippets



	use \Nbml\AutoLoader\ClassAutoLoader;
	use \Nbml\AutoLoader\ViewAutoLoader;
	use \Nbml\Compiler;

	);
	$classAutoLoader
					->addIncludePath(__DIR__ . '/../library')
					->register();

	$viewAutoLoader = new ViewAutoLoader();
	$viewAutoLoader
					->setCompilerDefaultDestinationDir(__DIR__ . '/../tmp')
					->setAlwaysCompile(true)
					->addIncludePath(__DIR__ . '/../library')
					->register();

	$viewCompiler = new Compiler();
	$viewCompiler
          ->addTagProcessor('\Nbml\MetadataTag\PublicMetadataTag')
          ->addTagProcessor('\Nbml\MetadataTag\StateMetadataTag')
          ->addTagProcessor('\Nbml\MetadataTag\OnDemandMetadataTag')
          ->addTagProcessor('\Nbml\MetadataTag\OnStateMetadataTag')
          ->addTagProcessor('\Nbml\MetadataTag\CssMetadataTag')
          ->addTagProcessor('\Nbml\MetadataTag\JsMetadataTag');

	$viewAutoLoader->setViewCompiler($viewCompiler);

The installer assumes, that you have following folders structure:

* public

	* index.php
* library

	* Nbml
* tmp

And now step by step. We include files of Autoloaders classes (ViewAutoLoader and ClassAutoLoader).
Then we should initialise ClassAutoLoader in order to properly load nbml compiler's classes.

	$classAutoLoader = new ClassAutoLoader();
	$classAutoLoader
			->addIncludePath(__DIR__ . '/../library')
			->register();

Hence we can without worries initialise autoloader to the *.nbml classes

	$viewAutoLoader = new ViewAutoLoader();
	$viewAutoLoader
			->setCompilerDefaultDestinationDir(__DIR__ . '/../tmp')
			->setAlwaysCompile(true)
			->addIncludePath(__DIR__ . '/../library')
			->register();

The foregoing script assumes, that *.nbml files are located in library folder, and also that after compilation they would be placed
in tmp folder. Make sure www server has privileges to write to this folder.
The Autoloader is set, that regardless of whether file was changed or not, it will be
compiled each time the autoloader is invoked. It consumes so much time, 
that in production environment this option
should be turned off. When the option setAlwaysCompile is set to false, the compiler will be run **only** in case
when the time of last change of *.nbml file is greater than time of last change of generated *.php file.

Then, what remains, is creating a compiler instance and adding it to autoloader.

	$viewCompiler = new Compiler();
	$viewCompiler
        ->addTagProcessor('\Nbml\MetadataTag\PublicMetadataTag')
        ->addTagProcessor('\Nbml\MetadataTag\StateMetadataTag')
        ...
	$viewAutoLoader->setViewCompiler($viewCompiler);

This operation is separated from ViewAutoLoader in purpose to allow more customisation - you can create your own compiler,
or extend the existing one completely as you wish.
Standard [metadata tags][metadata-tags] are included. On this place you can include your own tags, or disable
unused ones to improve code clarity.


## Instantiation using Composer (recommended method) [instantiation-composer]

Nbml can be also found in packagist, what makes using composer much simpler.
I will show how we can make use of composer to establish a new project.

Let us assume, that we have following structure of folders / files:

* public

	* index.php
* src

	* MyNamespace
* tmp
* composer.json
* composer.phar

The content of our **composer.json** file should be as follows:

	{
		"

	$exampleComponent = new \MyNamespace\Example();
	echo $exampleComponent

In the moment of using class \MyNamespace\Example, a file MyNamespace/Example/Example.nbml shall be downloaded, compiled to class 
\MyNamespace\Example and included (
 /**
         * @var $this \Nbml\Component
         */ 

	  }
	}

Of course it is only an operating scheme, if you are interested in particular compilation,
simply check how file 
Example.php looks like in reality.


# Why should I use the nbml? [why-should-i-use-it]

PHP is a language, that is itself a system of templates. Writing websites 
utilizing pure html+js+css is the best solution. The problem is, that if you separate view from controller in PHP, the views are not precise, that means it's unknown what variables can the template accept. IDE is not able to prompt, what can be executed in given template. The coder doesn't know, what variables have been left to him by programmer.

Here the nbml comes to aid. Thanks to him we are still creating templates in HTML+PHP, but this time the contract between 
coder and programmer is clear. The coder knows what does he have in particular view, and the programmer is happy because he
has an object:) Nobody will ever confuse variables names, because IDE without problems parses
generated classes
and prompts available options and variables' types.

Thanks to this solution you get full **objected view**. You create a tree of light components. But you create it in HTML - so applying skins is trivial.
This solution is completely non-invasive and you can without any counter-indications use 
nbml, parallel
with other libraries.


# Hello World example [hello-world-example]

As it is common, the first step in new language should be creating a program Hello World :)
The nbml obviously risen to the occasion, and presents you such a program.

I assume you have such folders' structure:

* library

	* Nbml
* public

	* HelloWorld

		* HelloWorld.nbml
	* index.php

We will use provided sandbox in order to initialize the intepreter.

file **index.php**

	
	$viewAutoLoader = 


	class HelloWorld extends \Nbml\Component\Application
	{

	    static public $PATH = '/var/www/hello_world/HelloWorld/HelloWorld.nbml';

	    /**
	     * @return \HelloWorld
	     */
	    static public function create()
	    {
	        return new \HelloWorld();
	    }

	    protected $options = array();

	    public function __construct($options = array())
	    {
	        parent::__construct($options);
	    }


	    /**
	     * @return \HelloWorld
	     */
	    public function __invoke()
	    {
	        ob_start();

	        
 /**
	     * @var $this \Nbml\Component\Application
	     */
	        

	        $this->text = ob_get_clean();
	        return $this;
	    }
	}




# Metadata Tags [metadata-tags]

The nbml uses phpdoc for objects definitions. For example such construction:

	 /**
	 * @var $this \Nbml\Component
	 * @var $message string
	 */ 
 /**
	 * @var $this \Nbml\Component
	 *
	 * [Public] @var $message string('Hello World!')
	 */ 

	$helloComponent = new HelloWorld();
	echo $helloComponent->message(); //Hello World!
	$helloComponent->message('Hello Internet!');
	echo $helloComponent->message(); //Hello Internet!
	echo $helloComponent; //<div class..../>

Using of the Metadata tag \[Public\] shall cause creating a public getter and setter for private variable $message.


## Metadata Tags - State [metadata-tags-state]

Metadata tag [\[State\]][metadata-tags-state] causes adding a state to given component. Variables defined as [\[State\]][metadata-tags-state] should be boolean.
Enabling one state will cause disabling other ones.

Let us consider following exemplary button component:

**Button.nbml**

	 /**
	 * @var $this \Nbml\Component
	 *
	 * [State] @var $normalState boolean(true)
	 * [State] @var $selectedState boolean(false)
	 */ 


	$button = new Button();
	var_dump($button->normalState()); //true
	$button->selectedState(true);
	var_dump($button->normalState()); //false
	echo $button;

Setting a variable selectedState on true, will cause other state's variables to be set on false.
One often uses metatag [\[State\]][metadata-tags-state] in collaboration with metatag [\[OnState\]][metadata-tags-on-state]


## Metadata Tags - OnState [metadata-tags-on-state]

Setting on a particular component the metatag [\[OnState\]][metadata-tags-on-state] will sets a condition on a particular variable.
**The variable will be initialised only in case, when the component finds itself in a given state.**
In other case its value will be an empty string.

Metadata tag [\[OnState\]][metadata-tags-on-state]
accepts one argument `name` defining the name of state, in which given variable has to initialise. The argument `name` is a default argument, so there is no need to write `[OnState(name='stateName')]`,one can use the shortened form: `[OnState('stateName')]`.

Let us consider a Button case:

**Button.nbml**

	 /**
	 * @var $this \Nbml\Component
	 *
	 * [State] @var $normalState boolean(true)
	 * [State] @var $selectedState boolean(false)
	 *
	 * [OnState('selectedState')] @var $selectedClass string('selected')
	 */ 
 /**
	 * @var $this \Nbml\Component
	 *
	 * [State] @var $normalState boolean(true)
	 * [State] @var $selectedState boolean(false)
	 *
	 * [OnState('selectedState')]
	 * [Public]
	 * @var $selectedClass string('selected')
	 *
	 * [Public] @var $href string('#')
	 * [Public] @var $label string
	 */ 
 /**
	 * @var $this \Nbml\Component
	 *
	 * [OnDemand]
	 * @var $subComponent \Nbml\Component
	 */ 
 if(rand(0, 9) > 4): 
 endif; 
 /**
	 * [Css('myComponent.css')]
	 * @var $this \Nbml\Component
	 */ 
 /**
	 * @var $this \Nbml\Component\Application
	 *
	 * [Css('/css/styles.css')]
	 */ 
 /**
	 * [Css('/css/styles.css')]
	 * @var $this \Nbml\Component\Application
	 */ 


	class HelloMetadataTag extends \Nbml\MetadataTag\AbstractMetadataTag
	{
	    static function getMetadataTagName()
	    {
	        return 'Hello';
	    }

	    public function getInitializationCode()
	    {
	        $nameUnderscored = $this->variable->getNameUnderscored();
	        $default = $this->variable->getDefaultValue();
	        return '$this->options[\'' . $nameUnderscored . '\'] = '
	            . '\'Hello \' . ' .  $default . ';';
	    }
	}

In order to use it, one has to add it to compiler in such way:

	$viewCompiler->addTagProcessor('\HelloMetadataTag')

From this now it is possible to use metadata tag `[Hello]`

**HelloComponent.nbml**

	 /**
	 * @var $this \Nbml\Component
	 *
	 * [Hello] @var $miwa string('Miwa')
	 */