# 07. __Plugins__

[![+Professional Support](https://www.totaljs.com/img/badge-support.svg)](https://www.totaljs.com/support/) [![+Chat with contributors](https://www.totaljs.com/img/badge-chat.svg)](https://messenger.totaljs.com)

`+v15` Plugins are targeted for dynamic parts which can be removed when aren't used. Plugins are the best way for dynamic pages, forms, windows, etc. in __SPA__ / Single Page Applications. 

__Topics__:

- [Declaration](#)
- [Properties](#)
- [Methods](#)
- [Delegates](#)
- [How to call plugin `exports`?](#)
- [How to get instance of some plugin?](#)
- [Best practices](#)

__Good to know__:

- a plugin is removed when the parent element of the `<script>` is removed
- a plugin is removed when the plugin with the same name is initialized again
- [__Example with Plugins__](https://github.com/totaljs/emptyproject-jcomponent)
- [Total.js CMS uses Plugins in admin area](https://github.com/totaljs/cms)

> __IMPORTANT__: `events` or `watchers` declared in the plugin scope will be removed automatically if the plugin is removed

## Declaration

- a plugin `name` can contain `a-z` chars only (no numbers or white characters)

```javascript
PLUGIN('name_of_plugin', function(exports) {
	
	// You can define your custom functions or properties
	exports.myfunction_1 = function() {
		console.log('something');
	};
	
	exports.myfunction_2 = function() {
		console.log('something');
	};    
	
	exports.myfunction_N = function() {
		console.log('something');        
	};
	
	// 2 way data-binding watcher:
	WATCH('some.path', function(path, value) {
		// ...
	});
	
	// Events
	ON('some.event', fucntion(req) {
		// ...
	});

});
```

### Properties

```javascript
PLUGIN('name_of_plugin', function(exports) {
	
	// A parent element of the <script> element
	// {jQuery}
	exports.element;
	
	// A plugin name
	// {String}
	exports.name;
	
});
```

### Methods

```javascript
PLUGIN('name_of_plugin', function(exports) {

	exports.something = function() {
		
		// Method: scope()
		// Enables a private scope for global methods like GET(), SET(), etc..
		// +v17
		exports.scope();

		console.log(GET('?.name'));
		// Will be evaluated as GET('name_of_plugin.name');
		
		SET('?.age', 30);
		// Will be evaluated as SET('name_of_plugin.age', 30);

		// Good to know:
		// Another "plugin.scope()" can rewrite current scope.
	};
		
});
```

### Delegates

Plugins support only the one delegate `destroy`. This delegate is executed when the plugin will be destroyed.

```javascript
PLUGIN('name_of_plugin', function(exports) {
	
	exports.destroy = function() {
		// is executed when the plugin is destroyed  
	};
	
}); 
```

## How to call plugin `exports`?

This is very easy, you can use `EXEC` method: 

```javascript
EXEC('name_of_plugin/myfunction_1', arg1, arg2, argN);
```

## How to get instance of some plugin?

You can get instance of the plugin very easy, just call `PLUGIN(name)` without second argument, for example:

```javascript
var exports = PLUGIN('name_of_plugin');
if (exports)
	exports.myfunction_1();   
```

## Best practices

- keep __Plugins__ as independent `.html` files
- I recommend to use Plugin names with lower-case