Chapter 3. How to Extend OTRS

Table of Contents

Writing a new OTRS frontend module
What we want to write
Default Config File
Frontend Module
Core Module
Template File
Language File
Summary
Using the power of the OTRS module layers
Authentication and user management
Agent Authentication Module
Authentication Synchronisation Module
Customer Authentication Module
Preferences
Customer User Preferences Module
Queue Preferences Module
Service Preferences Module
SLA Preferences Module
Other core functions
Log Module
Output Filter
Stats Module
Ticket Number Generator Modules
Ticket Event Module
Frontend Modules
Dashboard Module
Notification Module
Ticket Menu Module
Generic Interface Modules
Network Transport
Mapping
Invoker
Operation
Scheduler Task Handler Modules
Task Handler
Dynamic Fields
Overview
Dynamic Fields Framework
Dynamic Field Interaction With Frontend Modules
How To Extend The Dynamic Fields
Creating A New Dynamic Field
Creating a Dynamic Field Functionality Extension
Old Module Descriptions
Navigation Module
Customer Navigation Module
Ticket PostMaster Module
Ticket Menu Module

Writing a new OTRS frontend module

In this chapter, the writing of a new OTRS module is illustrated on the basis of a simple small program. Necessary prerequisite is an OTRS development environment as specified in the chapter of the same name.

What we want to write

We want to write a little OTRS module that displays the text 'Hello World' when called up. First of all we must build the directory /Hello World for the module in the developer directory. In this directory, all directories existent in OTRS can be created. Each module should at least contain the following directories:

Kernel
Kernel/System
Kernel/Modules
Kernel/Output/HTML/Standard
Kernel/Config
Kernel/Config/Files
Kernel/Language

Default Config File

The creation of a module registration facilitates the display of the new module in OTRS. Therefore we create a file '/Kernel/Config/Files/HelloWorld.xml'. In this file, we create a new config element. The impact of the various settings is described in the chapter 'Config Mechanism'.

<?xml version="1.0" encoding="UTF-8" ?>
<otrs_config version="1.0" init="Application">
        <ConfigItem Name="Frontend::Module###AgentHelloWorld" Required="1" Valid="1">
        <Description Translatable="1">FrontendModuleRegistration for HelloWorld module.</Description>
        <Group>HelloWorld</Group>
        <SubGroup>Frontend::Agent::ModuleRegistration</SubGroup>
        <Setting>
            <FrontendModuleReg>
                <Title>HelloWorld</Title>
                <Group>users</Group>
                <Description>HelloWorld</Description>
                <NavBarName>HelloWorld</NavBarName>
                <NavBar>
                    <Description>HelloWorld</Description>
                    <Name>HelloWorld</Name>
                    <Link>Action=AgentHelloWorld</Link>
                    <NavBar>HelloWorld</NavBar>
                    <Type>Menu</Type>
                    <Prio>8400</Prio>
                    <Block>ItemArea</Block>
                </NavBar>
            </FrontendModuleReg>
        </Setting>
    </ConfigItem>
</otrs_config>
        

Frontend Module

After creating the links and executing the Sysconfig, a new module with the name 'HelloWorld' is displayed. When calling it up, an error message is displayed as OTRS cannot find the matching frontend module yet. This is the next thing to be created. To do so, we create the following file:

# --
# Kernel/Modules/AgentHelloWorld.pm - frontend module
# Copyright (C) (year) (name of author) (email of author)
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --

package Kernel::Modules::AgentHelloWorld;

use strict;
use warnings;

use Kernel::System::HelloWorld;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless ($Self, $Type);

    # check needed objects
    for (qw(ParamObject DBObject TicketObject LayoutObject LogObject QueueObject ConfigObject EncodeObject MainObject)) {
        if ( !$Self->{$_} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
        }
    }

    # create needed objects
    $Self->{HelloWorldObject} = Kernel::System::HelloWorld->new(%Param);

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;
    my %Data = ();

    $Data{HelloWorldText} = $Self->{HelloWorldObject}->GetHelloWorldText();

    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HelloWorld");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'AgentHelloWorld',
    );
    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}

1;
        

Core Module

Next, we create the file for the core module "/HelloWorld/Kernel/System/HelloWorld.pm" with the following content:

# --
# Kernel/System/HelloWorld.pm - core module
# Copyright (C) (year) (name of author) (email of author)
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --

package Kernel::System::HelloWorld;

use strict;
use warnings;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {};
    bless ($Self, $Type);

    return $Self;
}

sub GetHelloWorldText {
    my ( $Self, %Param ) = @_;

    return 'Hello World!';
}

1;
        

Template File

The last thing missing before the new module can run is the relevant HTML template. Thus, we create the following file:

# --
# Kernel/Output/HTML/Standard/AgentHelloWorld.tt - overview
# Copyright (C) (year) (name of author) (email of author)
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
<h1>[% Translate("Overview") | html %]: [% Translate("HelloWorld") %]</h1>
<p>
    [% Data.HelloWorldText | Translate() | html %]
</p>
        

The module is working now and displays the text 'Hello World' when called.

Language File

If the text 'Hello World!' is to be translated into for instance German, you can create a translation file for this language in HelloWorld/Kernel/Language/de_AgentHelloWorld.pm. Example:

package Kernel::Language::de_AgentHelloWorld;

use strict;
use warnings;

sub Data {
    my $Self = shift;

    $Self->{Translation}->{'Hello World!'} = 'Hallo Welt!';

    return 1;
}
1;
        

Summary

The example given above shows that it is not too difficult to write a new module for OTRS. It is important, though, to make sure that the module and file name are unique and thus do not interfere with the framework or other expansion modules. When a module is finished, an OPM package must be generated from it (see chapter Package Building).