Publi

Gestionar desde PHP los archivos Javascript que necesitará nuestra página web

photo-1469173479606-ada03df615ac
A medida que las webs se van complicando, sobre todo en las páginas modernas, van necesitando más y más archivos Javascript para poder ejecutarse, y lo malo es que estos archivos deben incluirse por orden, ya que un mínimo fallo aquí puede hacer que nuestra aplicación web no funcione correctamente. Por otro lado, también tenemos el caso de que para incluir un script, debemos incluir también varias dependencias (algunas obligatorias, otras opcionales).

Con esta clase quiero hacer una primera aproximación a la solución del problema:
myjs.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
  /**
   *************************************************************
   * @file myjs.class.php
   *************************************************************/


class Myjs
{
  protected $commonScripts = array('lib/backbone' => array('aliases' => array('backbone', 'bkbn'),
                               'depends' => array('!underscore', 'jquery'),
                               ),
                   'lib/jquery-ui' => array('aliases' => array('jquery-ui', 'jqueryui'),
                                'depends' => array('!jquery')
                                ),
                   'lib/jquery' => array('aliases' => array('jquery', '$'),
                             ),
                   'lib/underscore' => array('aliases' => array('underscore')),
                   'myscript' => array('depends' => array('!backbone', 'jquery', '!jqueryui', '!extraDepend')),
                   'lib/contextMenu' => array('aliases' => array('contextMenu', 'context'),
                                  'depends' => array('!jquery-ui', 'jquery',)),

                   );
  protected $scripts = array();

  /**
   * Finds script in commonScripts array
   *
   * @param $script Script to find
   */

  private function findScript($script)
  {
    if (isset($this->commonScripts[$script]))
      return $script;

    foreach ($this->commonScripts as $_script => $options)
      {
    if (isset($options['aliases']))
      {
        if (in_array($script, $options['aliases']))
          return $_script;
      }
      }
    return false;
  }

  /**
   * Adds a new Javascript to our project
   *
   * @param $script Script name or path
   * @param $options Script options
   */

  function addScript($script, $options = array())
  {
    $foundScript = $this->findScript($script);

    if ($foundScript)
      $script = $foundScript;

    /* The script has already been added */
    if (isset($this->scripts[$script]))
      return;

    if ($foundScript)
      {
    /* Merge dependencies from commonscripts and dependencies given by the user */
    $options['depends'] = array_merge((isset($this->commonScripts[$foundScript]['depends']))?$this->commonScripts[$foundScript]['depends']:array(), (isset($options['depends']))?$options['depends']:array());
      }
    else
      $options['depends'] = array();

    foreach ($options['depends'] as $depend)
      {
    if ($depend[0]=='!')
      $this->addScript(substr($depend, 1));
      }

    $this->scripts[$script] = $options;
  }

  /**
   * Ask an script if there is any other script before him
   *
   * @param $script Script to ask to
   * @param $script options
   * @param $ordered Array of ordered scripts
   */

  function askScript($script, $options, &$ordered)
  {
    if (in_array($script, $ordered))
      return;
    if (!empty($options['depends']))
      {
    foreach ($options['depends'] as $dep)
      {
        if (isset($this->scripts[$dep]))
          {
        $this->askScript($this->scripts[$dep], $ordered);
          }
      }
      }
    $ordered[] = $script;
  }

  /**
   * Writes <script type="text/javascript" src="scriptpath.js"></script> for each
   * javascript file, in order.
   *
   */

  function sendScripts()
  {
    if (empty($this->scripts))
      return '';

    $ordered = array();
    foreach ($this->scripts as $script => $options)
      {
    $this->askScript($script, $options, $ordered);
      }
    $out='';

    foreach ($ordered as $script)
      {
    $out.='<script type="text/javascript" src="/js/'.$script.'.js"></script>'."\n";
      }
    return $out;
  }

  /**
   * Return scripts array (debug only)
   *
   */

  function scriptsArray()
  {
    return $this->scripts;
  }
}
?>

Al principio tenemos un array ($commonScripts), aquí pondremos información relativa a los javascripts que vamos incluyendo, como claves, debemos poner la ruta donde se encuentra el archivo javascript, el valor será un array donde podremos incluir:

  • aliases : Un array con las posibles formas que tendremos de llamar al script, por ejemplo, el nombre sin la ruta, omitiendo algunos símbolos, por ejemplo si incluimos jquery.min, podemos llamarlo directamente jquery
  • depends : Array con las dependencias, en este casi si la dependencia es obligatoria, debemos poner una exclamación (!) delante del archivo, para que éste también se incluya en el proyecto

Podríamos incluir algunas cosas más, por ejemplo una opción que incluya el script sólo en Internet Explorer , o dependiendo de la versión de Internet Explorer, para poder incluir hacks como html5shiv o json2, etc o que el archivo javascript incluya también archivos CSS (pero esto no está implementado en el ejemplo)

El método addScript() tendrá dos argumentos, por un lado el script y por otro las opciones (que son idénticas a los valores del array $commonScripts. Este método incluirá el archivo que se ha pedido y buscará las dependencias obligatorias para incluirlas también.

La gran funcionalidad del script reside en sendScripts() y askScript(), entre los dos repasan todos los Javascripts incluidos para ponerlos en orden, askScript, de forma recursiva, va comprobando las dependencias de cada uno de ellos, y cuando un script no tiene dependencias pendientes, se añade al array $ordered. Luego, desde sendScripts, se recorre el array $ordered y se envía la cadena necesaria para incluir los scripts.

Podemos hacer un pequeño script de prueba:

test.php

1
2
3
4
5
6
7
8
9
10
11
<?php

require_once("myjs.class.php");

$s = new Myjs();

$s->addScript('context');
$s->addScript('myscript');

echo $s->sendScripts();
?>

Podemos jugar con la forma en la que incluimos los scripts, incluirlos en diferente orden, o incluir sólo los scripts principales que queremos en nuestro programa, para que las dependencias se incluyan solas.

Actualización 14/10/2016 : Añadida foto principal.

Foto principal: Massimo Mancini

También podría interesarte....

Only 1 comment left Ir a comentario

  1. Pingback: Bitacoras.com /

Leave a Reply