# 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.                                                           |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.siteadministrator.com/developer-guide/advanced-topics/creating-a-module.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
