# Creating a Module

You're asked to create a new module for managing company's location information. We will call this module the `Locations` module.

### Step 1: Location of your module

There are two potential locations for your project. The `sa` module directory, and your application's module directory.

```
{project_root}
    └───siteadmin
        └───Modules
             ├───{AppModules}   <-- custom modules
             └───sa             <-- core modules
```

The general rule of thumb for identifying the home for your module is,

1. Application specific modules go in a custom app modules directory
2. Core SiteAdmin modules go in the `sa` modules directory.

#### Don't see a directory for custom modules?

If you're working with a fresh installation of SiteAdmin, you'll probably only see a `sa` directory in `{project_root}/sitadmin/modules`. For application specific modules, create a new directory. The directory name will be used for PSR-4 class autoloading, so it must be namespace friendly.

By convention, the application modules directory is named after your project, capital-cased. For example, if your project is called "Awesome Fishing Supplies", you might name the directory "AwesomeFishingSupplies." After naming your custom module directory, your directory structure should look like this:

```
{project_root}
    └───siteadmin
        └───Modules
             ├───AwesomeFishingSupplies <-- custom modules
             └───sa                     <-- core modules
```

### Step 2: Module Directory Structure

```
{project_root}
    └───siteadmin
        └───Modules
             ├───AwesomeFishingSupplies
             │     └───Locations
             │       └───src
             │       │   ├───classes
             │       │   │     ├───models
             │       │   ├───css
             │       │   ├───js
             │       │   └───views
             │       └───composer.json
             └───sa
```

**Classes**

The `classes` directory will contain all of your PHP classes. This will include controllers, repositories, configuration, and helpers.

**Classes/Models**

The `models` directory will contain all of your doctrine entities.

**CSS**

The `css` directory will contain all CSS stylesheets.

**JS**

The `js` directory will contain all JS scripts.

**Views**

The `views` directory will contain all templates for views and subviews.

### Step 3: Create Module Configuration File

All modules contain a configuration file. This file is located in the `{module_root}/classes` directory, and must match the **case sensitive** name of the module. For example, the configuration file for our `Locations` module configuration file will reside in `{module_root}/classes/LocationsConfig.php`.

{% code title="{module\_root}/classes/LocationsConfig.php" %}

```php
<?php

namespace AwesomeFishingSupplies\Locations;
​
use sa\application\moduleConfig;
​
class LocationsConfig extends moduleConfig
{
    /**
     * Code executed before module is initialized.
     * Generally, modRequests and event listeners reside here.
     */
    public static function init() {}
    
    /**
     * Module routes
     */
    public static function getRoutes() {}
    
    /**
     * SiteAdmin dashboard navigation items
     */
    public static function getNavigation() {}
    
    /**
     * Module settings
     * Will be editable from SiteAdmin's settings manager.
     */
    public static function getSettings() {}
}
```

{% endcode %}

### Step 4: Filling out the module's configuration

#### init()

The `init()` method contains code that is executed before the module is fully initialized. This is where you would place [modRequests](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/advanced-topics/modRequest.md), [event listeners](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/advanced-topics/events.md), or code that other parts of the module expect to be available.

#### getRoutes()

The `getRoutes()` method returns an array of the module's application and administrative routes. View the [routing documentation](https://app.gitbook.com/s/-LB7PTje97ARlss-zn8u/developer-guide/advanced-topics/routing.md) for more details.

#### getNavigation()

The `getNavigation()` method specifies all the module's administrative navigation links. These links will appear in the admin dashboard's main menu.

```php
<?php
...
public static function getNavigation() {
    return array(
        new navItem([
            "id"     => "awesomeFishingSupplies_locations",
            "name"   => "Locations",
            "icon"   => "fa fa-user",
            "parent" => "siteadmin_root"
        ]),
        new navItem([
            "id"      => "awesomeFishingSupplies_locations_index",
            "name"    => "All Locations",
            "routeid" => "awesomeFishingSupplies_locations",
            "parent"  => "awesomeFishingSupplies_locations"
        ]),
    );
}
```

| Parameter | Description                                                                                                                       |
| --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `id`      | A unique ID for the nav item. Name should be structured as `{vendor}_{module}_{action}`. Parent nav items won't have an `action`. |
| `name`    | The navigation item's label.                                                                                                      |
| `routeid` | The route that the nav item is linked to.                                                                                         |
| `parent`  | The `id` of the parent nav item. If the current nav item is the parent, set this value to `siteadmin_root`.                       |

#### getSettings()

The module's settings should be defined in the `getSettings()` method. This includes API keys, pagination options, test mode toggles, etc.

```php
<?php
...
public static function getSettings() {
    return array(
        'enable_test_mode' => array(
            'module' => 'Locations',
            'default' => true,
            'type' => 'boolean'
        ),
       'api_secret_key' => array(
           'module' => 'Locations', 
           'default' => '', 
           'type' => 'text'
       )
    );
}
```

| Parameter | Description                                                                                                                               |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `module`  | The name of the module associated with this setting. This name should be human readable (i.e instead of `PageEditor`, use `Page Editor`). |
| `default` | The setting's default value. Data type varies depending on the setting's `type` parameter.                                                |
| `type`    | The type of field. `Text` => text field. `boolean` => true/false radio buttons.                                                           |
