Sophie

Sophie

distrib > Mandriva > 2008.1 > i586 > media > contrib-updates > by-pkgid > c7095aefea7b97fbd2a596dcbfb9d481 > files > 9

asterisk-docs-1.4.26.1-1mdv2008.1.i586.rpm

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Developing for the Asterisk GUI</title><link rel="stylesheet" href="styles.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.69.1" /><link rel="start" href="index.html" title="Asterisk™: The Future of Telephony" /><link rel="up" href="asterisk-CHP-11.html" title="Chapter 11. The Asterisk GUI Framework" /><link rel="prev" href="I_sect111_tt1363.html" title="Installing the Asterisk GUI" /><link rel="next" href="asterisk-CHP-12.html" title="Chapter 12. Relational Database Integration" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Developing for the Asterisk GUI</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="I_sect111_tt1363.html">Prev</a> </td><th width="60%" align="center">Chapter 11. The Asterisk GUI Framework</th><td width="20%" align="right"> <a accesskey="n" href="asterisk-CHP-12.html">Next</a></td></tr></table><hr /></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="I_sect111_tt1376"></a>Developing for the Asterisk GUI</h2></div></div></div><p>Once you’ve installed the files for the Asterisk GUI,<a id="ch11_guideveloping" class="indexterm"></a> you can begin to play with developing for the GUI. Over the
    next few sections, we’ll walk through setting up the various components
    and putting them together to enhance and expand the capabilities of the
    GUI.</p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id4149423"></a>Issuing Manager Commands over HTTP</h3></div></div></div><p>The Asterisk <a id="I_indexterm11_tt1377" class="indexterm"></a><a id="I_indexterm11_tt1378" class="indexterm"></a><a id="I_indexterm11_tt1379" class="indexterm"></a>GUI issues commands to Asterisk by calling specially
      crafted URLs to the Asterisk web server. This section provides examples
      of some commonly used commands (actions) and the corresponding web
      server responses. These AMI URLs have the following general
      structure:</p><p>
          <a id="I_programlisting11_tt1380"></a></p><pre class="programlisting">http://hostname:8088/asterisk/rawman?action=<span class="emphasis"><em>command</em></span>&amp;....<span class="emphasis"><em>parameter=value pairs</em></span>...
http://hostname:8088/asterisk/manager?action=<span class="emphasis"><em>command</em></span>&amp;....<span class="emphasis"><em>parameter=value pairs</em></span>...
http://hostname:8088/asterisk/mxml?action=<span class="emphasis"><em>command</em></span>&amp;....<span class="emphasis"><em>parameter=value pairs</em></span>...</pre><p>
        </p><p>The difference between the <code class="literal">rawman</code>, <code class="literal">manager</code> and <code class="literal">mxml</code> URLs is important. The web server exports
      three different views of the AMI interface. If you use a <code class="literal">rawman</code> URL, the server returns a series of
      keyword/value pairs in the HTTP response. If you use a <code class="literal">manager</code> URL, the server returns the result
      formatted as HTML. In a similar style, if you use a <code class="literal">mxml</code> URL, the server returns the results
      formatted in XML. For modern Ajax-style applications, the <code class="literal">rawman</code> and <code class="literal">mxml</code> forms are probably more useful.<sup>[<a id="id4149563" href="#ftn.id4149563">132</a>]</sup></p><p>The actions that can be sent to the server, along with their
      parameters, are the ordinary manager commands described in <a href="asterisk-APP-F.html" title="Appendix F. Asterisk Manager Interface Actions">Appendix F, <i>Asterisk Manager Interface Actions</i></a>. Note that<a id="I_indexterm11_tt1381" class="indexterm"></a><a id="I_indexterm11_tt1382" class="indexterm"></a> the <code class="literal">LOGIN</code> and <code class="literal">CHALLENGE</code> actions are unique in that they
      aren’t sent to Asterisk itself, but are processed by the Manager
      interface to authenticate the user. If the user hasn’t authenticated
      correctly, the server returns an error response rather than sending the
      action to Asterisk for processing.</p><p>Let’s look at some commonly used actions, and see how we can use
      them to control the <span class="keep-together">server</span>.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4149633"></a>LOGIN</h4></div></div></div><p>The <code class="literal">LOGIN</code> command
        authenticates credentials for the Manager interface’s HTML view. Once
        you are logged in, Asterisk stores a cookie<a id="I_indexterm11_tt1383" class="indexterm"></a> on your browser (valid for the length of the
        <code class="literal">httptimeout</code> setting). This cookie is used to
        connect to the same session. The URL:</p><p>
            <code class="filename">http://localhost:8088/asterisk/rawman?action=login&amp;username=asterisk_http&amp;secret=gooey
        </code>
          </p><p>sends a login command to the web server that includes the
        credentials. If successful, the web server responds with:</p><a id="I_programlisting11_tt1384"></a><pre class="programlisting">Response: Success
Message:  Authentication accepted  </pre><p>This, of course, is a very simplistic way for a login to work.
        Sending the username and secret password in a URL is bad practice,
        though it’s very useful during development. A more appropriate way to
        handle the login, and an example of more complex command processing,
        is to use a challenge/response sequence. Issue a request like
        this:</p><p>
            <span><strong class="command">
              <code class="filename">http://localhost:8088/asterisk/rawman?action=challenge&amp;AuthType=md5</code>
            </strong></span>
          </p><p>The <code class="literal">CHALLENGE</code> command
        initiates a challenge/response sequence that can be used to log in a
        user. The server responds by sending a challenge (an arbitrary string)
        in the response:</p><a id="I_programlisting11_tt1385"></a><pre class="programlisting">Response: Success
Challenge: 113543555</pre><p>Your application answers the challenge by computing the MD5 hash
        of the challenge concatenated with the user’s password. Here’s how a
        user might manually calculate the MD5 hash:</p><a id="I_programlisting11_tt1386"></a><pre class="programlisting"># <strong class="userinput"><code>echo -n 113543555gooey | md5sum</code></strong>
           <code class="computeroutput">50a0f43ad4c9d99a39f1061cf7301d9a  -</code></pre><p>You can then use the calculated hash as the login key in a URL
        like this:</p><p>
            <code class="filename">http://localhost:8088/asterisk/rawman?action=login&amp;username=asterisk_http&amp;authtype=md5&amp;key=50a0f43ad4c9d99a39f1061cf7301d9a
        </code>
          </p><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>For security reasons, the login action must take place within
          five seconds of the challenge action. Note also that cookies must be
          enabled for the challenge/response to work, as the cookie ensures
          that the login action uses the same manager session ID as the
          challenge action.</p></div><p>If you use a <code class="literal">manager</code> URL to
        request the challenge (instead of using <code class="literal">rawman</code>), the response will be formatted as
        HTML:</p><p>
            <a id="I_programlisting11_tt1387"></a></p><pre class="programlisting">&lt;title&gt;Asterisk&amp;trade; Manager Interface&lt;/title&gt;
&lt;body bgcolor="#ffffff"&gt;
&lt;table align=center bgcolor="#f1f1f1" width="500"&gt;
&lt;tr&gt;&lt;td colspan="2" bgcolor="#f1f1ff"&gt;&lt;h1&gt;&amp;nbsp;&amp;nbsp;Manager Tester&lt;/h1&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Response&lt;/td&gt;&lt;td&gt;Success&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Challenge&lt;/td&gt;&lt;td&gt;113543555&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;</pre><p>
          </p><p>Similarly, if you use the <code class="literal">mxml</code> view instead, you will receive a
        response formatted as XML:<a id="I_programlisting11_tt1388"></a></p><pre class="programlisting">&lt;Ajax-response&gt;
   &lt;response type='object' id='unknown'&gt;
      &lt;generic response='Success' challenge='113543555' /&gt;
   &lt;/response&gt;
&lt;/Ajax-response&gt;</pre><p>Other than the formatting, there are no other differences
        between the three types of responses. For most applications, digging
        the challenge out of the keyword/value pairs will be much simpler than
        using <code class="literal">rawman</code> or <code class="literal">mxml</code> in a situation like this, where you
        don’t need to display the HTML to the user.</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4149872"></a>Transferring a call</h4></div></div></div><p>The <code class="literal">REDIRECT</code> <a id="I_indexterm11_tt1389" class="indexterm"></a>action can be used to transfer a call. Simply generate a
        URL such as:</p><p>
            <code class="filename">http://localhost:8088/asterisk/rawman?action=redirect&amp;channel=SIP/John-ae201e78&amp;priority=1&amp;exten=6001</code>
          </p><p>This URL transfers the specified channel to another extension
        and priority in the <span class="keep-together">dialplan</span>.
        The response to this action is:</p><a id="I_programlisting11_tt1390"></a><pre class="programlisting">Response: Success
Message: Redirect Successful        </pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4149932"></a>Reading a configuration file</h4></div></div></div><p>The <code class="literal">GETCONFIG</code> command
        <a id="I_indexterm11_tt1391" class="indexterm"></a>returns<a id="I_indexterm11_tt1392" class="indexterm"></a> the contents of a configuration file, or portion
        thereof. The URL:</p><p>
            <code class="filename">http://localhost:8088/asterisk/rawman?action=getconfig&amp;filename=users.conf</code>
          </p><p>returns the contents of the <code class="filename">users.conf</code> file. <a id="I_indexterm11_tt1393" class="indexterm"></a>The Asterisk GUI uses this functionality to present the
        current Asterisk configuration to the end user. The response looks
        like this:</p><a id="I_programlisting11_tt1394"></a><pre class="programlisting">Response: Success
   Category-000000: general
   Line-000000-000000: fullname=New User
   Line-000000-000001: userbase=6000
   Line-000000-000002: hasvoicemail=yes
   Line-000000-000003: hassip=yes
   Line-000000-000004: hasiax=yes
   Line-000000-000005: hasmanager=no
   Line-000000-000006: callwaiting=yes
   Line-000000-000007: threewaycalling=yes
   Line-000000-000008: callwaitingcallerid=yes
   Line-000000-000009: transfer=yes
   Line-000000-000010: canpark=yes
   Line-000000-000011: cancallforward=yes
   Line-000000-000012: callreturn=yes
   Line-000000-000013: callgroup=1
   Line-000000-000014: pickupgroup=1
   Line-000000-000015: host=dynamic
   Category-000001: 6007
   Line-000001-000000: fullname=Bill Savage
   Line-000001-000001: secret=1234
   Line-000001-000002: email=bsavage@digium.com
   Line-000001-000003: cid_number=6001
   Line-000001-000004: zapchan=
   Line-000001-000005: context=numberplan-custom-1
   Line-000001-000006: hasvoicemail=yes
   Line-000001-000007: hasdirectory=no
   Line-000001-000008: hassip=yes
   Line-000001-000009: hasiax=yes
   Line-000001-000010: hasmanager=no
   Line-000001-000011: callwaiting=yes
   Line-000001-000012: threewaycalling=yes
   Line-000001-000013: mailbox=6007
   Line-000001-000014: hasagent=yes
   Line-000001-000015: group=
</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150024"></a>Updating configuration files using UPDATECONFIG</h4></div></div></div><p>The <code class="literal">UPDATECONFIG</code>
        action<a id="I_indexterm11_tt1395" class="indexterm"></a> is used to update one or more settings in a
        configuration file. For example, to delete a user you should use a URL
        like this:</p><p>
            <span><strong class="command">
              <code class="filename">http://localhost:8088/asterisk/rawman?action=updateconfig&amp;reload=yes&amp;srcfilename=users.conf&amp;dstfilename=users.conf&amp;Action-000000=delcat&amp;Cat-000000=6003&amp;Var-000000=&amp;Value-000000=</code>
            </strong></span>
          </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150072"></a>Error response</h4></div></div></div><p>A user must be logged in to the web server before any other
        commands can be issued. Any of the commands we’ve discussed will
        return an error response if the user is not authenticated. If it’s not
        given by an authenticated user, this URI <span><strong class="command"><code class="filename">http://localhost:8088/asterisk/rawman?action=ping
        </code></strong></span>returns this response to indicate an
        error:</p><a id="I_programlisting11_tt1396"></a><pre class="programlisting">Response: Error
Message:  Authentication Required    </pre></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id4150108"></a>Ajax, AJAM, and Asterisk</h3></div></div></div><p>As an <a id="I_indexterm11_tt1397" class="indexterm"></a>acronym, <a id="ch11_ajax" class="indexterm"></a><a id="ch11_ajam" class="indexterm"></a><a id="ch11_1ajam" class="indexterm"></a>Ajax stands for <em class="firstterm">Asynchronous JavaScript and
      XML</em>. While the term includes the words asynchronous and XML,
      this does not mean that you can make only asynchronous requests, nor are
      you required to use XML. Some authors describe Ajax as simply a
      combination of HTML, <a id="I_indexterm11_tt1398" class="indexterm"></a><a id="I_indexterm11_tt1399" class="indexterm"></a><a id="I_indexterm11_tt1400" class="indexterm"></a><a id="I_indexterm11_tt1401" class="indexterm"></a>JavaScript, DHTML, and DOM. The next generation browsers,
      such as Mozilla/Firefox,<a id="I_indexterm11_tt1402" class="indexterm"></a><a id="I_indexterm11_tt1403" class="indexterm"></a> use an<a id="I_indexterm11_tt1404" class="indexterm"></a> XMLHttpRequest (a JavaScript object) to send an
      asynchronous request to the server. The request is made in the
      background and processed by the server.</p><p>Back on the browser, the result is handled by a callback: whatever
      the server returns can be stored and used to update the page being
      displayed. For Internet Explorer 5 or later, the XMLHttp ActiveX
      object<a id="I_indexterm11_tt1405" class="indexterm"></a> serves the same purpose.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150265"></a>Form processing in a traditional web application</h4></div></div></div><p>HTML forms <a id="I_indexterm11_tt1406" class="indexterm"></a>are usually submitted by using a submit button (<code class="literal">type=submit</code>). When the user clicks the
        submit button, processing stops, and doesn’t continue until the server
        returns a new page:</p><a id="I_programlisting11_tt1407"></a><pre class="programlisting">&lt;FORM action="login.php" method="POST"&gt;
  &lt;input type=text name="username"&gt;
  &lt;input type=password name="password"&gt;
  &lt;input type=submit&gt; 
&lt;/FORM&gt;</pre><p>Before going any further with Ajax or JavaScript, let’s take a
        look at how a traditional web application works. Traditional web
        applications use HTML’s <code class="literal">&lt;FORM&gt;</code> element to define a form in
        which all of the parameters a user needs to send to the server are
        defined. In addition the <code class="literal">action="login.php"</code> informs the browser where
        to send all of these variables. The <code class="literal">method="POST"</code> tells the browser how to send
        these variables to the server.</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150332"></a>Form processing in an Ajax application</h4></div></div></div><p>An Ajax application uses JavaScript <a id="I_indexterm11_tt1408" class="indexterm"></a>to send the contents of a form to the server. If you
        have made the request asynchronously, your JavaScript code doesn’t
        wait for the server to respond. This also means that you can let the
        users continue to interact with the page, even though a request may be
        taking place in the background. This can be dangerous and, thus, you
        may want to restrict certain actions until a request has completed.
        The browser, by default, gives no visual indication that a request is
        being made in the background. It is your responsibility to inform the
        user of the progress of a request. Here’s the code for submitting the
        contents of the username and password fields via Ajax:</p><a id="I_programlisting11_tt1409"></a><pre class="programlisting">&lt;script language="javascript" type="text/javascript"&gt;
 function submitform(){
  var uname = document.getElementById("username").value;
  var pwd = document.getElementById("password").value;
  // xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); // IE 7
  // xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5
  xmlHttp = new XMLHttpRequest(); // Mozilla or Firefox
  
  var url = "/rawman?action=login&amp;username=" + escape(uname) + "&amp;secret=" + escape(pwd);
  
  xmlHttp.open("GET", url, true);
  xmlHttp.onreadystatechange = dosomething; 
  // dosomething() would be another JavaScript function
  xmlHttp.send(null);
}
&lt;/script&gt;    </pre><p>The <code class="literal">getElementById()</code>
        method<a id="I_indexterm11_tt1410" class="indexterm"></a> reads the value of the username and the password
        fields. This code then gets an XMLHttpRequest object,<a id="I_indexterm11_tt1411" class="indexterm"></a> which it uses to send these values back to the server.
        Note that the kind of object you need depends on whether your users
        are using Internet Explorer 7, 5,<a id="I_indexterm11_tt1412" class="indexterm"></a> or Mozilla/Firefox. It’s fairly easy to write code to
        handle all of these situations, or to use a library like Prototype to
        handle platform independence for you. The username and password are
        encoded in a URL and sent to the server. The call to <code class="literal">xmlHttp.onreadystatechange</code> registers a
        handler to process the result that the server returns to us.</p><p>This code only deals with making the XMLHttp request, and it
        tells the browser to call the <code class="literal">dosomething()</code> function when there is a
        response from the server. Here’s a <code class="literal">dosomething()</code> function that handles
        this response:</p><a id="I_programlisting11_tt1413"></a><pre class="programlisting">&lt;script language="javascript" type="text/javascript"&gt;
  function dosomething() {
    if (xmlHttp.readyState == 4) {
      var login_response = xmlHttp.responseText;
    }
  }
&lt;/script&gt;</pre><p>
            </p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>Make sure that each XMLHttp step has completed (with either
            success or failure) before performing the next one.</p></div><p>
          </p><p>This function is called whenever there’s a change in the state
        of the HTTP request. The <code class="literal">if</code>
        statement saves the response only if the request’s <code class="literal">readyState</code> is 4, which means that the
        request has completed. The JavaScript variable <code class="literal">login_response</code> now contains the response of
        the login page.</p><p>Note that this is very far from being production-ready code. In
        particular, the simplistic username and password handling is
        appropriate for testing, but would be a serious security problem in a
        production system—even if the application is used only on a private
        network. To build more robust and secure password handling, use the
        challenge/response system presented earlier. If you want to learn more
        about writing Ajax web applications, we recommend <span class="emphasis"><em>Head Rush
        Ajax</em></span> by Brett McLaughlin (O’Reilly).</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150522"></a>The Prototype framework</h4></div></div></div><p>Prototype (<a href="http://prototypejs.org" target="_top">http://prototypejs.org</a>) is a
        <a id="I_indexterm11_tt1414" class="indexterm"></a>JavaScript framework released under an MIT-style
        license. Prototype can make your job extremely easy while developing
        an Ajax application. It provides many ways to make your code shorter
        and clearer. For example, in the <code class="literal">submitform</code>
        function, the call to <code class="literal">document.getElementById()</code> can be replaced by
        the <code class="literal">$()</code> function. Likewise, the
        call to <code class="literal">value</code> to get the DOM
        element’s content can be replaced with a call to <code class="literal">$F()</code>. Thus, <code class="literal">document.getElementById("username").value</code>
        becomes simply <code class="literal">$F('username')</code>; the
        result is code that’s much simpler and more readable.</p><p>Prototype also makes it easy to make XMLHttp requests in an
        elegant manner. Using Prototype’s <code class="literal">Ajax</code> object, the <code class="literal">submitform()</code> function can be rewritten
        as:</p><a id="I_programlisting11_tt1415"></a><pre class="programlisting">&lt;script language="javascript" type="text/javascript"&gt;
function submitform(){
   var url = '/rawman';
   var pars = 'username=' + escape($F('username')) + '&amp;secret=' + escape($F('password'));
   
var myAjax = new Ajax.Request( url, 
  { method: 'get', 
    parameters: pars, 
    onComplete: dosomething
  });

}
&lt;/script&gt;</pre><p>Not only is this code much shorter, you don’t have to write
        browser-specific code in your web pages; Prototype takes care of the
        differences between Mozilla/Firefox and the various versions of
        Internet Explorer. Furthermore, it takes care of testing the request’s
        <code class="literal">readyState</code>, so you leave that
        annoying <code class="literal">if</code> statement out of your
        handler. Prototype has lots of built-in functions, some of which have
        been extensively used in the Asterisk framework. There’s no room to
        discuss them here, but for more information, see the Short Cuts
        <span class="emphasis"><em>Prototype Quick Reference</em></span> by Scott Raymond and
        <span class="emphasis"><em>Prototype and Scriptaculous: Taking the Pain Out of
        JavaScript</em></span> by Chris Angus, both from<a id="I_indexterm11_tt1416" class="indexterm"></a><a id="I_indexterm11_tt1417" class="indexterm"></a><a id="I_indexterm11_tt1418" class="indexterm"></a> O’Reilly.</p></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id4150699"></a>Customization of the GUI</h3></div></div></div><p>Now that<a id="ch11_custom" class="indexterm"></a> we’ve explored the different pieces that form the
      foundation of the Asterisk GUI, we have what we need to be able to
      explore the GUI itself and modify it to fit our needs. To get to the
      Asterisk GUI, go to the following address in your browser:
      <code class="filename">http://localhost:8088/asterisk/static/config/cfgbasic.html</code>.</p><p>Looking at Figure 11-1 might lead you to conclude that the
      Asterisk GUI is simply one more Asterisk GUI in an already crowded
      space. Nothing could be further from the truth. This GUI doesn’t just
      allow you to tweak it, it practically begs you to. In this section we
      are going to discuss how you can modify the GUI and use AJAM to build
      your own extensions to the GUI. In order to benefit the most from this
      information, you need some HTML and JavaScript knowledge.</p><p>
          </p><div class="figure"><a id="asterisk_11_asterisk_GUI"></a><p class="title"><b>Figure 11.1. A screenshot of the Asterisk GUI</b></p><div class="mediaobject"><a id="I_mediaobject11_tt1419"></a><img src="figs/web/ast2_1101.png" alt="A screenshot of the Asterisk GUI" /></div></div><p>
        </p><p>The GUI home page is named <code class="filename">cfgbasic.html</code>. All other pages are loaded
      into the iframe contained within the <code class="filename">cfgbasic.html</code> page. By default, <code class="filename">cfgbasic.html</code> loads <code class="filename">home.html</code> into the main frame.</p><p>For most changes to the GUI, you’ll eventually need to
      modify<a id="I_indexterm11_tt1420" class="indexterm"></a> <code class="filename">cfgbasic.html</code>, which
      is the login screen.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4150841"></a>Adding a new tab to the GUI</h4></div></div></div><p>As an example of customizing the Asterisk GUI, let’s create a
        new tab that displays the contents of <code class="filename">extensions.conf</code>. First, we need to create a
        file and put it in the <code class="filename">/var/lib/asterisk/static-html/config</code>
        directory. In this example, we’ll name the file <code class="filename">test.html</code>:</p><a id="I_programlisting11_tt1421"></a><pre class="programlisting">&lt;script src="scripts/prototype.js"&gt;&lt;/script&gt;
&lt;script src="scripts/astman.js"&gt;&lt;/script&gt;
&lt;script&gt;
function localAjaxinit() {
       parent.loadscreen(this);
       makerequest('g','extensions.conf', '' , function(t){
               $('ExtensionsDotConf').innerHTML = "&lt;PRE&gt;" + t + "&lt;/PRE&gt;";
       });
}
&lt;/script&gt;
&lt;body onload="localAjaxinit()" bgcolor="EFEFEF"&gt;
       &lt;div id="ExtensionsDotConf"&gt;&lt;/div&gt;
&lt;/body&gt;</pre><p>This code simply displays the configuration of the <code class="filename">extensions.conf</code> file. Obviously it’s a very
        simple example, but it shows the fundamentals of creating a new page
        for the Asterisk GUI. Let’s walk through the example step by
        step.</p><p>The first line tells the browser to load the Prototype library.
        The second line tells the browser to load the <code class="literal">astman.js</code> file, which contains much of the
        code designed to interact with the Manager interface.</p><p>Next, we define a function called <code class="literal">localAjaxinit</code>. The<a id="I_indexterm11_tt1422" class="indexterm"></a> <code class="literal">localAjaxinit</code>
        function first tells this page’s parent (<code class="filename">cfgbasic.html</code> in this case) to run the
        <code class="literal">loadscreen</code> function, passing in
        this page as the parameter. This causes the main GUI screen to load
        our new <code class="filename">test.html</code> inside the
        iframe. The second thing we do inside the <code class="literal">localAjaxinit</code> function is to use the
        <code class="literal">makerequest</code> function. The <code class="literal">makerequest</code> function <a id="I_indexterm11_tt1423" class="indexterm"></a>is defined in <code class="filename">astman.js</code> and makes it very convenient to
        make requests to the web server.<sup>[<a id="id4150991" href="#ftn.id4150991">133</a>]</sup></p><p>The first parameter of the <code class="literal">makerequest</code> function specifies what type of
        request is being made. It can be set to any of the following:</p><div class="variablelist"><dl><dt><span class="term">
                <code class="literal">'g'</code>
              </span></dt><dd><p>Use the<a id="I_indexterm11_tt1424" class="indexterm"></a> <code class="literal">GetConfig</code>
              action to retrieve the configuration from the configuration file
              specified in the second parameter.</p></dd><dt><span class="term">
                <code class="literal">'u'</code>
              </span></dt><dd><p>Use the<a id="I_indexterm11_tt1425" class="indexterm"></a> <code class="literal">UpdateConfig</code>
              action to update the configuration in the configuration file
              specified in the second parameter. The third parameter to the
              function specifies the configuration data that should be
              updated.</p></dd><dt><span class="term">
                <code class="literal">''</code>
              </span></dt><dd><p>If the first parameter to the <code class="literal">makerequest</code> function is a <a id="I_indexterm11_tt1426" class="indexterm"></a><a id="I_indexterm11_tt1427" class="indexterm"></a>set of single quotes, then the custom action
              specified in the third parameter will be sent.</p></dd></dl></div><p>The fourth parameter is the callback function that will be
        called with the response to the Ajax request.</p><div class="sidebar"><a id="I_sidebar11_tt1428"></a><p class="title"><b>Examples of Using makerequest</b></p><p>As an example, the following code snippet shows three
          different ways to use the <code class="literal">makerequest</code> function. In the first,
          we’ll get the configuration data from <code class="filename">users.conf</code>. In the second, we’ll update
          <code class="filename">musiconhold.conf</code> and change the
          value of the <code class="literal">random</code> setting in
          the <code class="literal">default</code> class. Last but not
          least, we’ll call the <code class="literal">Ping</code>
          action. Each of them sets a callback function named <code class="literal">t</code> that simply replaces the contents of the
          <code class="literal">div</code> with the response of the Ajax
          call.</p><a id="I_programlisting11_tt1429"></a><pre class="programlisting">makerequest( 'g', 'users.conf', '' , 
    function(t) { $('ExtensionsDotConf').innerHTML = "&lt;PRE&gt;" + t + 
    "&lt;/PRE&gt;"; } );
makerequest( 'u', 'musiconhold.conf', 

'&amp;Action-000000=update&amp;Cat-000000=default&amp;Var-000000=random&amp;Value-
    000000=yes' , 
    function(t) { $('ExtensionsDotConf').innerHTML = "&lt;PRE&gt;" + t + 
    "&lt;/PRE&gt;"; } );

makerequest( '', '', 'action=Ping' , 
   function(t) { $('ExtensionsDotConf').innerHTML = "&lt;PRE&gt;" + t + 
   "&lt;/PRE&gt;"; } );
</pre></div><p>The rest of our <code class="filename">test.html</code>
        simply contains an HTML body with a <code class="literal">div</code> element, which is where we’ll place the
        configuration data when we get it. Note that the HTML body tag has an
        <code class="literal">onload</code> attribute, which causes the
        browser to execute the <code class="literal">localAjaxinit</code> function once the page has
        finished loading.</p><p>Now that we’ve created a new page, we need to edit <code class="filename">cfgbasic.html</code> to add this page as a panel
        in the GUI. Open <code class="filename">cfgbasic.html</code>
        and search for a JavaScript function named <code class="literal">returnpanels</code> and insert this code in the
        list of panels, where you would like your panel to appear:</p><a id="I_programlisting11_tt1430"></a><pre class="programlisting">newpanel( ["Test", "test.html", "Test"]);</pre><p>Now reload the GUI in your browser. You should see a new tab on
        the lefthand side named <code class="literal">Test</code> that
        displays the configuration values for <code class="filename">extensions.conf</code> when clicked.</p><p>While there’s a lot more to learn about the AJAM interface and
        the Asterisk GUI, this example should show just how easy it is to add
        new functionality to the GUI. In this next example, we’ll show how
        simple it is to expose a setting from the configuration files in the
        GUI.</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id4151330"></a>Exposing configuration settings in the GUI</h4></div></div></div><p>As explained earlier, one of the unique benefits of the Asterisk
        GUI over the other graphical frontends to Asterisk is that it updates
        the configuration files in place, taking special care not to overwrite
        or erase any extra settings you might have in your configuration
        files. To show just how easy it is to expose new settings in the GUI,
        we’ll add a simple checkbox to the GUI to make it possible to set the
        <code class="literal">nat</code> setting in <code class="filename">users.conf</code>.</p><p>If you open the GUI and click on the tab labeled <code class="literal">Users</code>, the GUI loads the file named
        <code class="filename">users.html</code> in the iframe. Let’s
        open up <code class="filename">users.html</code> (usually
        located in <code class="filename">/var/lib/asterisk/static-http/config</code>) and
        begin modifying it to add our checkbox.</p><p>First, search near the top of the file where a variable named
        <code class="literal">fieldnames</code> is defined. This
        variable contains a list of all of the field names that will be set by
        this page of the GUI. Simply add <code class="literal">nat</code> to the end of the list, or add the
        following line directly below the current definition for <code class="literal">fieldnames</code>.</p><a id="I_programlisting11_tt1431"></a><pre class="programlisting">fieldnames.push('nat');</pre><p>This tells the Asterisk GUI that we want to be able to see the
        value of <code class="literal">nat</code> and to be able to set
        it as well. In order to see or set the value, however, we need to add
        an element to the HTML form. To do that, search <code class="filename">users.html</code> for the IAX checkbox, and add
        the following lines between it and the CTI checkbox.</p><a id="I_programlisting11_tt1432"></a><pre class="programlisting"> &lt;tr&gt;
   &lt;td align=right&gt;&lt;input type='checkbox' id='nat'&gt;&lt;/td&gt;
   &lt;td&gt;NAT&lt;/td&gt;
&lt;/tr&gt;</pre><p>Simply reload the page, and that’s all there is to it. With just
        a few lines of additional code, we’re able to expose the <code class="literal">nat</code> setting to the GUI. It couldn’t be much
        simpler!<a id="I_indexterm11_tt1433" class="indexterm"></a></p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>As you’re developing for the Asterisk GUI, you’ll probably
          find that debugging Ajax and JavaScript code can be somewhat
          difficult at times. We strongly suggest you make use of an extension
          to Mozilla Firefox named Firebug that greatly simplifies the task of
          debugging Ajax, JavaScript, and HTML. Check it out at <a href="http://www.getfirebug.com" target="_top">http://www.getfirebug.com</a>.
          There is also a scaled-down version for Internet Explorer known as
          Firebug Lite, which is available for download at the same web
          site.</p></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id4151495"></a>For More Information</h3></div></div></div><p>Over the course of this chapter, we’ve introduced you to the
      Asterisk GUI and the AJAM framework. We’ve covered the architecture of
      how the GUI works, and how to modify the GUI. If you would like more
      information on developing a graphical interface for Asterisk, please
      refer to the GUI Developers <a id="I_indexterm11_tt1434" class="indexterm"></a>Guide located <a id="I_indexterm11_tt1435" class="indexterm"></a>at <a href="http://asterisknow.org/developers/gui-guide" target="_top">http://asterisknow.org/developers/gui-guide</a>.</p></div><div class="footnotes"><br /><hr width="100" align="left" /><div class="footnote"><p><sup>[<a id="ftn.id4149563" href="#id4149563">132</a>] </sup>By similar reasoning, the <code class="literal">manager</code> form is much easier for humans to
          use for debugging purposes.</p></div><div class="footnote"><p><sup>[<a id="ftn.id4150991" href="#id4150991">133</a>] </sup>In reality, <code class="literal">makerequest</code>
            is a simple wrapper around a call to Prototype’s <code class="literal">Ajax.Request</code> method.</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="I_sect111_tt1363.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="asterisk-CHP-11.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="asterisk-CHP-12.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Installing the Asterisk GUI </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 12. Relational Database Integration</td></tr></table></div><div xmlns="" id="svn-footer"><hr /><p>You are reading <em>Asterisk: The Future of Telephony</em> (2nd Edition for Asterisk 1.4), by Jim van Meggelen, Jared Smith, and Leif Madsen.<br />
       This work is licensed under the <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative Commons Attribution-Noncommercial-No Derivative Works License v3.0</a>.<br />
       To submit comments, corrections, or other contributions to the text, please visit <a href="http://oreilly.com/catalog/9780596510480/">http://www.oreilly.com/</a>.</p></div></body></html>