Crear Snippets

From MODx Wiki

Jump to: navigation, search


Contents

Tips

Acá vamos a ver algunoas de las mejores prácticas para que los developers de add-ons utilicen. No tienes para qué seguirlo al pié de la letra, pero es bueno tenerlo en mente.

Para obtener la ID del documento actual document

$id = $modx->documentIdentifier;

Nunca Utilizar:

$id = $modx->getDocumentIdentifier('id');

ya que tu snippet va a causar que las Friendly URLs dejen de funcionar al usar tu snippet, además de otros resultados indeseables

Siempre usar comillas simples, no usar dobles

Cuando utilizas comillas simples, tu texto es parseado más rapido por php.

echo "MODx"; // mal
echo 'MODx'; // bien!

Usar concatenación en vez de poner las variables en strings con doble comilla

Cuando defines un string en comillas dobles es posible poner $variables dentro de ese string y va a ser parseado por php, esto, lamentablemente complica la legibilidad del código. Además es más rápido utilizar concatenación

echo "My name is $name"; // mal
echo 'My name is'.$name; // bien!

Todas las variables, funciones y clases deben comenzar con las iniciales de tu nombre de recurso

Esto previene que exista una colisión de nombres y además es una buena práctica en general.

Variables:

$lang; // mal
$nrLang; // bien!, (cuando el recurso se llama NombreRecurso)

Nombres de función ("si no están dentro de una clase"):

function countRows() { ... } // mal
function nrCountRows() { ... } // bien!

Nombres de Clases:

class RowClass { ... } // mal
class RnRowClass { ... } // bien!

Nombre de las variables para que el formato del contenido pueda ser adivinado

Es bueno nombrar las variables para que el contenido pueda ser adivinado desde el nombre de la variable, además mejora la lecturabilidad del código, por ejemplo:

$country = "Japan"; // mal
$rnStrCountry = "Japan"; // bien!, 'Str' me dice que es un String
$rn_str_country = "Japan"; // también está ok.
 
$count = 1; // mal
$rnNrCount = 1; // bien!, 'Nr' nos dice que es un número
$rn_int_count = 1; // también está bien
 
$rows = array(); // bad
$rnArrayRows = array(); // bien!, 'Array' nos dice que es una variable del tipo Array
$nr_ar_rows; // bien!

Nombra las funciones para que su procedimiento y valor sean simples de deducir

Los nombres deben implicar lo que hacen, si tienen que retornar algo, que sea fácil de comprender el formato del valor retornado

function name($userid) { return $name; } // mal
function rnGetStrName($rnNrUserId) { return $rnStrName; } // bien!, una función que retorna un nombre del tipo String
function rnIsValidMember($rnNrUserId) { return true; } // bien!, una función que retorna un booleano

envuelve las funciones dentro de un !function_exists si el recurso es necesitado más de una vevz por página

Si tu llamas 2 veces a un snippet en una página, va a salir un error diciendo algo así "Cannot redeclare functionName()". para evitar eso debes crear un bloque condicional !function_exists para evitar tratar de crear una función ya declarada.

function rnCountRows() { ... } // mal
 
if(!function_exists(rnCountRows)) { // bien!
    function rnCountRows() { ... } 
}

Tu también puedes escribir todas las funciones y guardarlas en tu servidor web bajo /assets/snippets/[el nombre de tu snippet]/ y usar include_once para incluir todas las funciones.

Declarar o inicializar variables antes de utilizarlas

Esto nos protege contra la inyección de variables

echo $rnStrCountry; // mal
$rnStrCountry = 'Japan'; echo $rnStrCountry; // bien!
$rnStrCountry = ''; echo $rnStrCountry; // bien!

Variables y objectos creados durante la ejecución del recurso deben ser destruídas

Destruir variables y objetos que han sido creadas in tu snippet es una buena práctica, esto libera recursos de memoria en el servidor, esto siempre es bueno

$rnStrCountry = 'Japan'; // fin del recurso // mal
$rnStrCountry = 'Japan'; unset($rnStrCountry); // bien!

Unset es bueno hacerlo al final de la ejecución del recurso, solo en variables que no serán utilizadas despúes de eso. También si cargas un gran recurso en la memoria en el medio de tu código, sería una buena idea removerlo luego de utilizarlo sin necesidad de esperar hasta el término de la ejecución

Validar los valores de parámetros en un snippet mientras sea posible

Siempre debemos validar que la entrada del usuario sea la correcta

// Parametros : param=$timestamp;
$rnTimeStamp = $param; // mal
if (isTimestamp($param)) $rnTimeStamp = $param; // bien!

Los parámetros de los Snippets siempre deben tener un valor por defecto

Los parámetros configurables de un snippet siempre deben tener un valor por defecto. Esto es para evitar errores si algunos parámetros no son inicializados y además para simplificar al máximo la utilización del snippet desde el punto de vista del usuario.

Si algún parámetro no puede tener valores predefinidos, ellos deben ser chequeados en el código del snippet y si el valor no ha sido seteado, un error debería ser desplegado al usuario.

$rnStrName = $param; // mal
$rnStrName = isset($param) ? $param : 'valor por defecto'; // bien!

Los snippets y plugins no deben contener código de la capa de presentación

Los snippets y plugins no deben contener código de la capa de presentación: la salida (X)HTML no debe ser agregada a la lógica del snippet, en vez de esto, utilizaremos las habilidades de templating de MODx para insetar la salida en un placeholder u obtener el template de salida desde un chunk. Esto tiene muchas ventajas, entre ellas que tu recurso será más flexible para los usuarios finales, la lecturabilidad del código se merjora, la traducción se simplifica, etc..

// mal
$output = '<p>'.$rnStrName.'</p>';
return $output;
 
// bien!
//en el template, el usuario tiene: <p>[+rnStrName+]</p>
$modx->setPlaceholder('rnStrName', $rnStrName);
return;
 
// aún mejor!
// en el chunk el usuario tiene: <p>[+rnStrName+]</p>
// el usuario para el parametro $nombre_del_chunk al snippet
$chunk = $modx->getChunk($nombre_del_chunk);
$output = str_replace('[+rnStrName+]', $rnStrName, $chunk);
return $output;

Usar strftime() para formatear una fecha en vez de date()

Tu deberías usar strftime() en vez de date() para formatear la salida de una fecha. Esto provee internacionalización de los valores de salida, strftime() es afectado por set_local() cuando date() no lo es.

// mal 
$rnStrFormat = 'F j, Y, g:i a'; 
$rnStrToday = date($rnStrFormat); // March 10, 2006, 1:23 pm
 
// bien!
// asumiendo que el usuario ha seteado su posición en alguna parte, como por ejemplo en confic.inc.php
$locale = setlocale(LC_ALL, 'de_DE.UTF-8');
 
$rnStrFormat = '%B %d, %Y, %H:%S';
$rnStrToday = strftime($rnStrFormat); // März 23, 2006, 13:23

Dejar solo seteos de configuración en el código del snipet y utilizar php include topara incluír el código de la lógica

Si tu snippet posee un código muy largo, utiliza archivos externos para guardar la lógica del programa, de esta manera es más fácil organizar el codigo y su lógica. Es buena idea también organizar el código en distintos archivos externos también, por ejemplo, la lógica en un archivo, funciones en otro, etc...

Es buena práctica dejar el mínimo posible de código para que el usuario pegue en el espacio de los snippets, de esta manera se previene que el usuario pueda equivocarse y generar un error. Ahora cada vez más los hostings está utilizando el mod_security, el cual puede provocar errores al usuario al grabar un snippet en modx si mod_security previene algunos strings en el POST data.

Además usa include_once() en vez de include(), require() y require_once() para prevenir que los archivos sean incluídos muchas veces si un snippet tiene que ejecutarse más de una vez en una misma página. Debes utilizar $modx->config['base_path'] en la ruta de tu snippet para incluir los archivos en ambientes que tienen restcricción de open_basedir en efecto.

//mal
$rnNrCount = 10;
for ($rnIndex = 0; $rnIndex < $rnNrCount; $rnIndex++) {
 ... etc, muchas líneas de código ...
}
 
//bien!
$rnStrName = isset($rnStrName) ? $rnStrName : 'valor por defecto';
include_once($modx->config['base_path'].'assets/snippets/yoursnippet/yourcode.inc.php');

Crear cabeceras descriptivas en tu código

Es una buena práctica tener cabeceras descriptivas de comentarios en to código PHP que dejen claros los siguientes temas:

  • Nombre del recurso
  • Nombre del autor
  • Nick del autor (ej tu nombre en el foro de MODx)
  • Version
  • compatibilidad con versiones de MODx
  • Fecha de entrega
  • Descripción corta

Tu debes siempre además proveer la siguiente documentación para tu recurso:

  • descripción larga
  • ejemplos de uso
  • una lista de parámetros y sus explicaciones (si es necesario)
  • Una lista de modificaciones (Información corta acerca de bugfixes, nuevas funcionalidades, rewrites, etc.)
  • Una lista de los chunks que se necesitan
  • Una lista de placeholders (si es que hay alguno)
  • Una lista de los archivos que son necesitados para que el recurso funcione (Ej. dependencias a otros recursos, rutas de instalación, permisos requeridos, etc.)
  • lista de las cosas por hacer (si alguna)

Comment your code as much as possible

It's good to comment your code as much as possible to increase readability and help collaborative work.


Objectify Your Code

If you're writing a lot of common functions, put them into a class! Don't create a huge list of functions with no bearing, when you could be writing solid Object-Oriented Programming.

For example, a good snippet would have the config parameters in the snippet TPL, include its actual logic in an external PHP file, and be run via a class instantiation and method calls. i.e.:

  1. <?php
  2. require_once($modx->config['base_path']."assets/snippets/paintboard/paintboard.inc.php");
  3.  
  4. $PaintBoard = new PaintBoard(array(
  5. 'width' => 400,
  6. 'height' => 300,
  7. 'title' => 'My Canvas',
  8. ));
  9.  
  10. $modx->setPlaceholder('pbCanvas',$Paintboard->render());
  11. ?>

where the constructor of the class takes a config array, sets it up, and then the render() method renders the PaintBoard.

The paintboard.inc.php class can look like this (PHP5 demo):

  1. <?php
  2. class PaintBoard {
  3. function __construct($config) {
  4. // do logic based on array here...
  5. }
  6.  
  7. public function render() {
  8. // draw code here...
  9. return $output;
  10. }
  11.  
  12. private function createColorPalette() {
  13. // code here
  14. }
  15.  
  16. // .. more functions ..
  17. }
  18. ?>

The benefits to this are simple: the main logic code is separated from the connector (the snippet code), and the output is put in a placeholder. Thus, you get MVC (Model-View-Controller) programming style, which is optimal.

It also prevents you from overwriting PHP variables used in other snippets or MODx situations. Not to mention, this cleans up the code big time.

Do not use short PHP open tags in your external script files

To have your resource supported on many different server environments, avoid using short php open tags.

<? .... ?> //bad
<?php .... ?> //good
Personal tools