updated synonyms to 1.5

This commit is contained in:
Bachir Soussi Chiadmi
2016-11-05 17:54:56 +01:00
parent 773e7fbddd
commit 252abe9b0e
51 changed files with 6500 additions and 2484 deletions

View File

@@ -12,3 +12,7 @@ weight = -1
[synonyms_behavior_implementation]
title = Creating a new behavior implementation
parent = synonyms
[synonyms_behavior_implementation_field_based]
title = Creating a new behavior implementation from a field
parent = synonyms_behavior_implementation

View File

@@ -1,18 +1,38 @@
The Synonyms module provides various functionality targeted at handling synonymous (similar) spelling of the same name.
The Synonyms module provides various functionality targeted at handling synonymous (similar) spelling of the same name. This functionality is provided for all Drupal entities.
Currently the module only provides synonyms for Taxonomy Terms, though there are plans to extend it and to support synonyms for all entity types. There are few key concepts tightly integrated into Synonyms module that are worth knowing for the end user. They are:
<dt>Field independency</dt>
<dd>Synonyms can be stored in various manners in your database within fields attached to your entities. Since the fields are different (entity reference, text, etc) you can keep your synonyms in the most convenient way for you.</dd>
There are few key concepts tightly integrated into Synonyms module that are worth knowing for the end user. They are:
<dt>Storage abstraction</dt>
<dd>Synonyms can be stored in any way your business logic requires it... It may go from fields attached to entities down to custom tables and then all the way up to querying an external API. Putting it simple, you can keep your synonyms in the most convenient way for you.</dd>
<dt>Synonyms behaviors</dt>
<dd>Having a list of synonyms doesn't really help much; what you want to do is something productive with them. That's where synonyms behaviors whatsoever come on stage. They are abstract self sufficient units of behavior that do something productive with synonyms. For example, here we have the autocomplete behavior, which introduces autocomplete text fields that do look up not only by term name but by its synonyms too. Synonyms behaviors can be added through other contributed modules, you're not locked down to what Synonyms module has to offer you.</dd>
<dd>Having a list of synonyms doesn't really help much; what you want to do is something productive with them. That's where synonyms behaviors whatsoever come on stage. They are abstract self sufficient units of behavior operating on top of synonyms data that do something productive with it. For example, here we have the autocomplete behavior, which introduces autocomplete widgets that do look up not only by entity name but by its synonyms too. Synonyms behaviors can be added through other contributed modules, you're not locked down to what Synonyms module has to offer you.</dd>
<dt>Synonyms behavior implementations</dt>
<dd>Lastly, here is yet more abstract unit. Behavior implementations bridge between existing synonyms behaviors and existing fields that may contain synonyms. Imagine as if you had a table, where rows are fields attached to your entities and the columns are the existing synonyms behaviors. Behavior implementations fill in the cells of this table. So, for example, you could have behavior implementation for autocomplete feature for the entity reference field. It means that synonyms stored in entity reference fields can participate in the autocomplete functionality.</dd>
<dd>Lastly, here is yet more abstract unit. Behavior implementations bridge between existing synonyms behaviors and the synonyms storage abstraction. Imagine as if you had a bipartite graph, one side of the graph are behaviors, the other side is storage abstractions and lastly the edges of this graph would be implementations of behaviors for specific storage.</dd>
Let's cover each of these important concepts in details.
<p>Let's cover each of these important concepts in details.</p>
<h2>Field Independency</h2>
<h2>Synonyms behaviors</h2>
As stated above, your synonyms can be saved in many different field types. Synonyms module ships support for storing synonyms in the following field types:
<p>Synonyms behaviors are some useful for the end user features that leverage the synonyms data. Synonyms module ships with the following behaviors:</p>
<ul>
<li>Autocomplete: allows synonyms to participate in the synonyms friendly autocomplete functionality.</li>
<li>Select: allows synonyms to participate in the synonyms friendly select.</li>
<li>Search: (provided through "Synonyms Search" submodule) behavior that integrates synonyms with Search module, i.e. your nodes can be found not only by names of the terms they reference, but also by the synonyms of those terms. It also integrates with <a href="https://www.drupal.org/project/term_search">Term Search</a> module in the same manner: when searching for terms you can also find them by their synonyms.</li>
</ul>
<p>Other modules can introduce their own behaviors. If you are interested in introducing your own behavior, refer to <a href="&topic:synonyms/synonyms_behaviors&">synonyms behaviors</a> page.</p>
<h2>Storage abstraction</h2>
As stated above, your synonyms can be stored in about any kind of storage. On the other hand, no matter where they are stored, they can be used in synonyms behaviors and treated equally independently of their origin. Such decoupling of synonyms storage and synonyms manipulation gives an extra degree of freedom. Synonyms module provides the following types of storage:
<dt>Entity properties</dt>
<dd>As long as your entity property is stored in database, "Entity Property Synonyms Provider" submodule can extract them from there and give them good usage with synonyms behaviors. One good example would be to enable user's "email" field in "autocomplete" behavior, so users can find one another through autocomplete widget not only by username but by the email as well.</dd>
<dt>Fields</dt>
<dd>Many entities may have fields attached to them. "Field Synonyms Provider" submodule exposes field values as possible synonyms for the entities they belong to. Again, a good example would be to introduce a text field "Typos" and have it enabled in "autocomplete" behavior. This way you can cover at least the most common misspellings in your autocomplete widget.</dd>
<dt>Anything else</dt>
<dd>Synonyms module is built to be easily extended to cover custom needs of its client base. If you want to store your synonyms elsewhere, you can do so with a minimal required amount of code. Refer to <a href="&topic:synonyms/synonyms_behavior_implementation&">writing custom behavior implementation</a> for documentation on how to do it.</dd>
<p>The "Field Synonyms Provider" submodule acts as a framework that exposes values from different field types into Synonyms core infrastructure. Out of the box this submodule covers the following field types:</p>
<ul>
<li>Text</li>
<li>Term reference</li>
@@ -20,60 +40,13 @@ As stated above, your synonyms can be saved in many different field types. Synon
<li>Number</li>
<li>Decimal</li>
<li>Float</li>
<li>Commerce product reference (you'll have to additionally enable "Synonyms Commerce" submodule for this one)</li>
</ul>
Other modules may extend this list by implementing "synonyms" behavior for other field types. The "synonyms" behavior is the most basic and general behavior that exists for synonyms. Basically, it's precisely the ability to extract synonyms from fields and to search for existence of a synonym within a field.
<h2>Synonyms behaviors</h2>
Synonyms behaviors are some useful for the end user features that leverage the synonyms data. Synonyms module ships with the following behaviors:
<ul>
<li>Synonyms: just the basic behavior which allows to extract synonyms from a field and to search for a synonym within a field. Normally we advice to enable this behavior for all fields that one way or another are seen as source of synonyms. This behavior has many various goodies, such as support for synonym-friendly Views contextual filter and panels argument, adding another entity as synonym, etc.</li>
<li>Autocomplete: allows synonyms to participate in the synonyms friendly autocomplete functionality.</li>
<li>Select: allows synonyms to participate in the synonyms friendly select.</li>
<li>Search: behavior that integrates synonyms with Search module, i.e. your nodes can be found not only by names of the terms they reference, but also by the synonyms of those terms. It also integrates with <a href="https://www.drupal.org/project/term_search">Term Search</a> module in the same manner: when searching for terms you can also find them by their synonyms.</li>
</ul>
Similarly, as with field independency, other modules can introduce their own behaviors. If you are interested in introducing your own behavior, refer to <a href="&topic:synonyms/synonyms_behaviors&">synonyms behaviors</a> page.
<p>Other modules may extend this list by implementing behaviors for other field types. Refer to <a href="&topic:synonyms/synonyms_behavior_implementation_field_based&">writing custom field-based behavior implementation</a> for more details.</p>
<h2>Behavior Implementations</h2>
Behavior implementations connect behaviors to field types. Synonyms module ships the following set of behavior implementations:
<table>
<thead>
<tr>
<th>Field type \ Behavior</th>
<th>General synonyms</th>
<th>Autocomplete</th>
<th>Select</th>
<th>Search</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>Text</b></td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
</tr>
<tr>
<td><b>Term reference</b></td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
</tr>
<tr>
<td><b>Entity reference</b></td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
<td>implemented</td>
</tr>
</tbody>
</table>
<p>Behavior implementations connect behaviors to different types of synonyms storage. Out of the box Synonyms module provides enough behavior implementations to probably cover majority of use cases. As stated above, be it not the case, you can always extend coverage further through implementing custom behavior implementations in your own module. Feel free to study the hooks at synonyms.api.php file. Also, you may find it useful to read about <a href="&topic:synonyms/synonyms_behavior_implementation&">writing custom behavior implementation</a>.</p>
Lastly, you as a website admin can enable or disable certain fields to participate in certain behaviors. So you have full control over how things get set up in your website. Additionally, some behaviors may provide additional configs, for example, the autocomplete behavior will ask you with what wording to suggest a term if it was matched by one of its synonyms.
The referenced above table may be extended through hooks that Synonyms module provides. Feel free to study the hooks at synonyms.api.php file. Also, you may find it useful to read about <a href="&topic:synonyms/synonyms_behavior_implementation&">writing custom behavior implementation</a>.
<p>Lastly, you as a website admin can enable or disable certain behavior implementations to participate in certain behaviors. So you have full control over how things get set up in your website. Additionally, some behaviors may provide configs, for example, the autocomplete behavior will ask you with what wording to suggest an entity if it was matched by one of its synonyms.</p>

View File

@@ -1,27 +1,29 @@
At this point you must possess good technical knowledge about what synonyms behaviors are. In this article we will show how you can implement an arbitrary behavior for an arbitrary field type.
<p>At this point you must possess good technical knowledge about what synonyms behaviors are. In this article we will show how you can implement an arbitrary behavior for an arbitrary storage.</p>
By implementing I mean to provide integration between a field type (between how that field type stores and encodes synonyms data in the database) and a synonym behavior (how that behavior requires to work with synonyms data). It must sound a bit too baked, but the ongoing paragraphs should shed more light onto it.
<p>By implementing I mean to provide integration between your storage and a synonym behavior (how that behavior requires to work with synonyms data). It must sound a bit too baked, but the ongoing paragraphs should shed more light onto it.</p>
Throughout writing your own synonyms behavior implementation you can always look into Synonyms module source code to get better understanding. You will find the behavior implementatios in <em>synonyms/includes/*SynonymsBehavior.class.inc</em> files.
<p>Throughout writing your own synonyms behavior implementation you can always look into Synonyms module source code to get better understanding. You will find the behavior implementations in <em>synonyms/synonyms_provider_{property,field}/includes/*SynonymsBehavior.class.inc</em> files.</p>
Creating a new implementation pretty much consists of 2 steps:
<p>Just one last question before we dive into technical details: is your storage eventually comes from a field? In case it does, you might benefit from reading <a href="&topic:synonyms/synonyms_behavior_implementation_field_based&">this page</a> as it narrates about implementing behaviors based on fields. You can leverage some abstractions from synonyms_provider_field submodule to make your life easier.</p>
<p>In case your storage is not field-based or you just happen to be Chuck Norris, read on! Creating a new implementation pretty much consists of 2 steps:</p>
<ol>
<li>Implementing behavior interface for a particular field type.</li>
<li>Notifying Synonyms module about your new PHP class and what field types and what behavior that PHP class is responsible for.</li>
<li>Implementing behavior interface for a particular storage type.</li>
<li>Notifying Synonyms module about your new behavior implementation, that is... for what behavior and what entity type and bundle you have implemented it.</li>
</ol>
Now let us see each of the steps in further details.
<p>Now let us see each of the steps in further details.</p>
<h2>Implementing behavior interface</h2>
Look up in behavior cTools plugin definition of your interest what interface it declares. The cTools plugin must be of type "behavior" owned by "synonyms" module. The interface is declared under the "interface" property. Read the documentation for that interface and write a PHP class that implements this interface. We cannot give more precise instructions about this step, because it all depends on the interface of the behavior.
<p>Look up in behavior cTools plugin definition of your interest what interface it declares. The cTools plugin must be of type <em>behavior</em> owned by <em>synonyms</em> module. The interface is declared under the <em>interface</em> property of the plugin definition. Read the documentation for that interface and write a PHP class that implements this interface for your particular storage. We cannot give more precise instructions about this step, because it all depends on the interface of the behavior.</p>
<h2>Notifying Synonyms module about your new implementation</h2>
For the purposes of such notification we have 2 hooks in Synonyms module:
<p>For the purposes of such notification we have the following hook in Synonyms module:</p>
<ul>
<li>hook_synonyms_behavior_implementation_info() to collect info from modules about existing behavior implementations</li>
<li>hook_synonyms_behavior_implementation_info_alter() to alter info about existing behavior implementations, for example, if you want to overwrite behavior implementation introduced in another module.</li>
<li><em>hook_synonyms_behavior_implementation_info()</em> to collect info from modules about existing behavior implementations</li>
</ul>
Implementing either of the 2 hooks is highly straight forward, you will just inform the Synonyms module for requested behavior for what field types you have implementations in what PHP classes. For more details, refer to synonyms.api.php file or look into synonyms_synonyms_behavior_implementation_info() function.
<p>Implementing the hook is highly straight forward, you will just inform the Synonyms module about what behavior implementations your module has to offer for a given behavior, entity type, and bundle. For more details, refer to <b>synonyms.api.php</b> file.</p>

View File

@@ -0,0 +1,32 @@
<p>If you are looking into implementing a behavior for storage that is eventually field-based, then you are on the right page! Since it is quite likely that many behavior implementations will be field-based, we have walked an extra mile to facilitate this particular case.</p>
<p>First of all, there is <em>synonyms_provider_field</em> submodule that:</p>
<ul>
<li>implements some behaviors for a set of common field types (see <a href="&topic:synonyms/synonyms&">this page</a> for particular details)</li>
<li>provides a good starting point for implementing behaviors for new field types</li>
</ul>
<p>Apparently, on this page we will focus on the 2nd item from the list above. If you implement a behavior for a new field type, then:</p>
<ul>
<li>Implement behavior interface for a particular field type. You are encouraged to extend your PHP class from <em>AbstractFieldSynonymsBehavior</em>. It has a few methods that will make your life easy. However, you are nowhere close to be obliged to use that abstract class; only as long as it helps you to achieve your goal.</li>
<li>Notify <em>synonyms_provider_field</em> submodule about availability of a new field type.</li>
</ul>
<p>Now let us see each of the steps in further details.</p>
<h2>Implementing behavior interface</h2>
<p>Look up in behavior cTools plugin definition of your interest what interface it declares. The cTools plugin must be of type <em>behavior</em> owned by <em>synonyms</em> module. The interface is declared under the <em>interface</em> property of the plugin definition. Read the documentation for that interface and write a PHP class that implements this interface for your particular field type. We cannot give more precise instructions about this step, because it all depends on the interface of the behavior.</p>
<h2>Notifying synonyms_provider_field submodule about your new implementation</h2>
<p>For the purposes of such notification we have the following hooks in <em>synonyms_provider_field</em> submodule:</p>
<ul>
<li><em>hook_synonyms_field_behavior_implementation_info()</em> to collect info from modules about field types available for synonyms behavior implementations</li>
<li><em>hook_synonyms_provider_field_behavior_implementation_info_alter()</em> to alter previously collected info from modules about field types available for synonyms behavior implementations</li>
</ul>
<p>Implementing either of the 2 hooks is highly straight forward, you will just inform the submodule about what field type is exposed to behavior implementation through what PHP class for a given behavior. Then the <em>synonyms_provider_field</em> submodule will analyze what fields are attached to what entity types and will convert this data into the format expected by the core Synonyms module. For more details, refer to <b>synonyms_provider_field.api.php</b> file.</p>

View File

@@ -1,40 +1,41 @@
If you made it up to here, then we expect you to already have decent understanding about what a synonyms behavior is. This page will try to explain how you could create a new one.
<p>If you made it up to here, then we expect you to already have decent understanding about what a synonyms behavior is. This page will try to explain how you could create a new one.</p>
In technical terms synonyms heaviors are just cTools plugins. Synonyms module defines its own plugin type: <em>behavior</em>, which is owned by <em>synonyms</em> module.
<p>Before I continue further with technical details, let me set certain framework on what synonyms behavior is and where is the line between a behavior and its implementation. Behavior is ultimately an interface that pursuits to deliver some end-user useful functionality. For the sake of example, let's consider the following behavior: whenever an email is sent to a user, our example behavior will swap his/her username in the 1st line of email body with a randomly picked up synonym of that user. This is behavior, because it narrates about behavioral pattern and is abstract to specifics of synonyms storage. Moreover, it sounds reasonable to be declared as a separate behavior (instead of using some pre-existing) because website admin may want to specify from what exact synonyms we can pick up a random nick name upon email being sent.</p>
Throught writing your own synonyms behavior you can always look into Synonyms module behaviors to get better understanding. You will find the plugins in <em>synonyms/plugins/behavior/*.inc</em> files. If you have never worked before with cTools plugins, if is also worthwhile to check out its <a href="&topic:ctools/plugins-implementing&">documentation</a>.
<p>On the other hand, if you are looking into providing synonyms data to behaviors, i.e. "implementing" behaviors for some specific storage facility, then you are on a wrong page. You better head off to <a href="&topic:synonyms/synonyms_behavior_implementation&">implementing behaviors</a> documentation.</p>
<p>Now that we have cleared the theoretical details, let's get busy with hands on experience. In technical terms synonyms behaviors are just cTools plugins. Synonyms module defines its own plugin type: <em>behavior</em>, which is owned by <em>synonyms</em> module. Throughout writing your own synonyms behavior you can always look into Synonyms module behaviors to get better understanding. You will find the plugins in <em>synonyms/plugins/behavior/*.inc</em> files. If you have never worked before with cTools plugins, it is also worthwhile to check out its <a href="&topic:ctools/plugins-implementing&">documentation</a>.</p>
<p>Your plugin implementation may (or must) have the following keys:</p>
Your plugin implementation may (or must) have the following keys:
<dt>title</dt>
<dd><b>Required</b> (string) Human-friendly translated title of your behavior.</dd>
<dt>description</dt>
<dd>(string) Human-friendly translated description of your behavior. Include a couple of words about what exactly it does and what end user functionality has.</dd>
<dt>settings form callback</dt>
<dd>(string) Name of a PHP function that will be invoked to generate settings form of your behavior. End user will fill out the form elements and the settings will be saved in the database for your plugin by Synonyms module. If your behavior does not require any additional configuration, you may omit this parameter. If you do require a settings form, then this callback function should receive the following input arguments: <ol>
<dd>(string) Name of a PHP function that will be invoked to generate settings form of your behavior. End user will fill out the form elements and the settings will be saved in the database for your plugin by Synonyms module. If your behavior does not require any additional configuration, you may omit this parameter. If you do require a settings form, then this callback function should receive the following input arguments:<ol>
<li><b>$form</b>: (array) form array into which your settings form elements will be merged. You do not have to change this $form. It is just provided to you in case you want to traverse through it for whatever reason.</li>
<li><b>&$form_state</b>: (array) form state array of the form into which your settings form elements will be merged. Again, you are not obliged to change or to use this argument, but it is provided to you in case you find it useful to keep some data in form state.</li>
<li><b>$settings</b>: (array) array of settings defined for your behavior. This array may be empty, if your behavior hasn't been saved yet, or it may contain previously saved settings. You should use content of this array as default values for your form elements.</li>
</ol>
Based on these input arguments, your settings form callback function should generate form elements array and return it.</dd>
<dt>interface</dt>
<dd><b>Required</b>: (string) Name of a PHP interface that represents your behavior. This interface should declare any methods that support your behavior. Implementations of your behavior will have to implement this interface for specific field types. To make it easier for you, think of the default synonyms behavior: it introduces the "synonyms" property on entities. Whenever that property is requested, the behavior code loops through enabled default synonyms behavior implementations asking to "extract synonyms from field values". So this "extract synonyms" method is declared in the interface. This way behavior implementations can implement the interface and therefore Synonyms without knowing anything specific about the underlying field type will be able to carry out its part - to get a list of synonyms. We advice to name the interfaces in the following fashion: <em>NameOfYourBehaviorHereSynonymsBehavior</em>. Also, your interface must extend the starting point of all synonyms behaviors - the <em>SynonymsBehavior</em> interface. If your behavior depends on functionality provided by other behaviors (for example, many behaviors depend on the general "synonyms" behavior), then your interface may extend the interface of that behavior (which would be to extend the <em>SynonymsSynonymsBehavior</em> in the case of "synonyms" behavior).</dd>
<dd><b>Required</b>: (string) Name of a PHP interface that represents your behavior. This interface should declare any methods that support your behavior. Implementations of your behavior will have to implement this interface for a specific storage. To make it easier for you, think of the default synonyms behavior: it introduces the "synonyms" property on entities. Whenever that property is requested, the behavior code loops through enabled behavior implementations asking to "extract synonyms from the storage". So this "extract synonyms" method is declared in the interface. This way behavior implementations can implement the interface and therefore Synonyms without knowing anything specific about the underlying storage will be able to carry out its part - to get a list of synonyms. We advice to name the interfaces in the following fashion: <em>NameOfYourBehaviorHereSynonymsBehavior</em>. Also, your interface must extend the starting point of all synonyms behaviors - the <em>SynonymsBehavior</em> interface. If your behavior depends on functionality provided by other behaviors, then your interface may extend the interface of that behavior.</dd>
<dt>enabled callback</dt>
<dd>(string) Name of a PHP function that will be invoked to notify your behavior that it has just been enabled on a new field. You could do any set-up routines in this function, if it is required by your behavior. If your behavior does not require any set up logic, you may omit this parameter. If you do specify it, then this callback function should receive the following input arguments:<ol>
<dd>(string) Name of a PHP function that will be invoked to notify your behavior that it has just been enabled on a new storage. You could do any set-up routines in this function, if it is required by your behavior. If your behavior does not require any set up logic, you may omit this parameter. If you do specify it, then this callback function should receive the following input arguments:<ol>
<li><b>$behavior_definition</b>: (array) Array of behavior definition. Basically it is your cTools plugin definition.</li>
<li><b>$settings</b>: (array) Array of settings for your behavior that is getting enabled. If your set up procedure depends on the behavior settings, then you can access the settings through this variable.</li>
<li><b>$instance</b>: (array) Array of field instance definition on which your behavior has just been enabled. Similarly as with $settings, if your set up procedure depends on field type, entity type, etc., then you can read this information from this var.</li>
<li><b>$behavior_implementation</b>: (array) Array of behavior implementation. It will contain various information specific to the storage on which your behavior have just been enabled. Also, behavior implementation, since it is enabled, will contain settings of your behavior which has provided website administrator. You can look up structure of this array in the comments of <em>synonyms_behavior_get()</em> function.</li>
</ol></dd>
<dt>disabled callback</dt>
<dd>(string) Name of a PHP function that will be invoked to notify your behavior that it has just been disabled on a field. You could do any tear-down routines in this function, if it is required by your behavior. If your behavior does not require any tear down logic, you may omit this parameter. If you do specify it, then this callback function should receive the following input arguments: <ol>
<dd>(string) Name of a PHP function that will be invoked to notify your behavior that it has just been disabled on a storage. You could do any tear-down routines in this function, if it is required by your behavior. If your behavior does not require any tear down logic, you may omit this parameter. If you do specify it, then this callback function should receive the following input arguments:<ol>
<li><b>$behavior_definition</b>: (array) Array of behavior definition. Basically it is your cTools plugin definition.</li>
<li><b>$behavior_implementation</b>: (array) Array of behavior implementation. It is a return of synonyms_behavior_get() function. This array will contain plenty of information about the context. Among other things it will include settings of your behavior.</li>
<li><b>$instance</b>: (array) Array of field instance definition on which your behavior has just been disabled. If your tear down procedure depends on field type, entity type, etc., then you can read this information from this var.</li>
<li><b>$behavior_implementation</b>: (array) Array of behavior implementation. It will contain various information specific to the storage on which your behavior have just been disabled. Also, behavior implementation will contain settings of your behavior which has provided website administrator. You can look up structure of this array in the comments of <em>synonyms_behavior_get()</em> function.</li>
</ol></dd>
Having said the above, let us wrap up on how you should create a new behavior:
<ol>
<li>Think through what you want your behavior to do and what interface will be required to support your behavior.</li>
<li>Declare your behavior interface, make sure to document and to well comment the interface methods. The better docs it has, the easier it will be for other developers to implement your behavior for new field types. Also, make sure your interface extends the necessary interfaces from other behaviors (if your behavior depends on the functionality of other behaviors).</li>
<li>Write PHP code that will use the interface to achieve some productive action. Depending on what your behavior does, it may be but not limited to implementing a hook, writing a custom PHP function, etc.</li>
<li>Probably you will want to implement your freshly created behavior for at least one field type. Otherwise your behavior won't have any synonyms to work with and will be useless. Read about implementing a behavior for new field types <a href="&topic:synonyms/synonyms_behavior_implementation&">here</a>.</li>
<li>Declare your behavior interface, make sure to document and to well comment the interface methods. The better docs it has, the easier it will be for other developers to implement your behavior for new storage types. Also, make sure your interface extends the necessary interfaces from other behaviors (if your behavior depends on the functionality of other behaviors).</li>
<li>Write PHP code that will use the interface to achieve some productive action. Depending on what your behavior does, it may be but not limited to implementing a hook, writing a custom PHP function, etc. For example, in our dummy "let me swap username with his synonym upon email being sent" case, this would materialize into implementing <em>hook_mail_alter()</em> where you'd have to process email body and swap all occurrences of username with a randomly picked synonym. You will definitely need <em>synonyms_behavior_get()</em> as it allows to load enabled behavior implementations for a given behavior.</li>
<li>Probably you will want to implement your freshly created behavior for at least one storage type. Otherwise your behavior won't have any synonyms to work with and therefore will be useless. Read about implementing a behavior for new storage types <a href="&topic:synonyms/synonyms_behavior_implementation&">here</a>.</li>
</ol>