¿Cuál es el concepto básico detrás de los ganchos?


120

Soy intermedio en PHP. Para pulir mis habilidades, empiezo a aprender Drupal 7. Mientras aprendía los conceptos de arquitectura de Drupal, los términos ganchos y bootstrapping me intrigaron mucho. Leí el libro "Desarrollo de Pro Drupal" y algo de documentación en drupal.org, pero es muy avanzado para mí aprender cómo funcionan los ganchos en Drupal para mostrar la página web.

¿Alguien puede decirme qué ganchos hay en palabras simples?

Respuestas:


107

Las otras respuestas son geniales, precisas y detalladas, pero no estoy seguro de que sean las "palabras simples" que explican los aspectos básicos del concepto que estaba buscando el autor de la pregunta.

Pienso en los ganchos como un punto donde el código se detiene y grita "¿ Alguien más tiene algo que agregar aquí? ". Cualquier módulo puede tener una función que responda a esto y se active con los datos apropiados que se le pasan en ese punto del código.

Un buen ejemplo directo es hook_node_delete () . Cualquier módulo puede usarlo para hacer que las cosas sucedan cada vez que se elimina un nodo. Los documentos le dicen que este gancho pasa al módulo el objeto de ese nodo eliminado para trabajar y describe otra información útil, como sobre el momento exacto de cuándo se llama (por ejemplo, antes de que los datos del nodo se eliminen realmente de la base de datos) , y donde en el código de Drupal se llama el gancho (que puede ser más de un lugar).

Puede explorar qué ganchos existen y averiguar qué datos se les pasan explorando cosas que comienzan con "gancho_" en la API de Drupal .

Los ganchos funcionan según las convenciones de un nombre: utilizando hook_node_deletecomo nuestro ejemplo, cuando el proceso de eliminación del nodo alcanza el punto donde se llama el gancho, para cada módulo con una función como esta, [modulename]_node_delete()donde la palabra gancho en el nombre del gancho se reemplaza con el nombre del módulo (p. Ej. my_amazing_module_node_delete()), esas funciones se llaman.

¿Por qué? Por lo tanto, cualquier módulo puede hacer cualquier cosa en estos puntos clave: por ejemplo, podría mirar el nodo eliminado y hacer cosas si cumple una determinada condición (por ejemplo, enviar un correo electrónico a un administrador o iniciar un proceso largo).

Algunos ganchos le permiten modificar cosas que se han generado justo antes de que se procesen. Por ejemplo, hook_menu_alter () le pasa los elementos del menú actual que el sistema ha generado. Cualquier módulo puede definir una función some_modulename_menu_alter () y mirarlos, opcionalmente cambiarlos (eliminar algunos, agregar algunos, ordenarlos ...) y volver a pasar el menú recién modificado.

Es simple, realmente potente y está en el corazón de cómo Drupal funciona como un sistema modular. Las implementaciones de ganchos están en el corazón de la mayoría de los módulos de Drupal.

Al mirar a través del código de un módulo de Drupal, puede detectar qué funciones provienen de los ganchos (en oposición a las funciones que simplemente se llaman desde el propio código del módulo), ya que la comunidad de Drupal impone una convención por la cual cada implementación de un gancho tiene un comente delante de esta manera (observe el bit "Implements hook _..."):

/**
 * Implements hook_some_hook().
 *
 * Some descriptive summary of what this does
 */
function my_amazing_module_some_hook() {

Algunos módulos que actúan como API definen sus propios ganchos. Por ejemplo, Vistas define muchos ganchos que le permiten agregar, leer y editar datos en varios puntos en el proceso de creación o visualización de una vista. Puede encontrar información sobre ganchos creados en módulos personalizados desde dos lugares (suponiendo que el módulo siga las convenciones, etc.):

Bootstrapping es, como explicaron otros, básicamente arrancar: no duplicaré las otras explicaciones claras y buenas.


53

Los ganchos, en su mayoría, son implementaciones de los patrones Visitor y Observer .

Una de las implementaciones de ganchos más comunes es hook_menu , que permite a los módulos registrar nuevas rutas dentro de un sistema Drupal.

function my_module_menu() {
  return array('myawesomefrontpage' => array(
    'page callback' => 'function_that_will_render_frontpage'
  ));
}

Un patrón muy frecuente en Drupal es tener un [DATATYPE]_infogancho y un [DATATYPE]_info_altergancho. Si desea crear un nuevo tipo de campo, implementará el correspondiente field_info -hook, y si desea manipular uno existente, implementará el correspondiente field_info_alter -hook.

Editar: como señala Chx en los comentarios, el patrón de observación está orientado a objetos, que Drupal 7 sigue siendo, en su mayoría, no. Sin embargo, hay una página wiki, programación de Drupal desde una perspectiva orientada a objetos (creada por JonBob el 4 de abril de 2005), que explica cómo Drupal utiliza patrones de código orientados a objetos a pesar de esto. Es interesante notar que menciona observadores, pero no visitantes.

Nota sobre Drupal 8 Esto aún es bastante temprano y está sujeto a cambios, pero quiero agregar que, si bien los ganchos han sido durante bastante tiempo el estándar de facto para agregar funcionalidad a Drupal, el concepto de complementos será mucho más visible en Drupal 8, y nos dará nuevas formas de interactuar con Core. Relevante tema , y documentación .


2
No se deje engañar por los patrones de diseño de OOP. Este no es uno. Los ganchos Drupal son AOP. Vea abajo.

@chx, aunque libremente admito que sabes mejor que yo :) y tu respuesta es correcta (lo voté) No interpreto que mi respuesta sea incorrecta. :) Si no está de acuerdo, me gustaría saber cómo he entendido mal los patrones de su implementación.
Letharion

44
Wikipedia: "El patrón de observador es un patrón de diseño de software en el que un objeto, llamado sujeto, mantiene una lista de sus dependientes, llamados observadores", aquí no hay ningún objeto que tenga observadores. El visitante es más turbio pero se aplica el mismo principio genérico: lo que no es OOP no puede tener patrones de OOP.

33

En términos simples, los ganchos son una especie de puentes que proporcionan una forma para que los módulos interactúen entre sí, alteren la estructura y los datos de los demás, proporcionen nuevos datos, etc.

En la mayoría de los casos, la palabra hook_en los nombres de las funciones se reemplaza por el nombre de su módulo, y eso proporciona una forma para que su módulo aproveche la operación de otro módulo. Por ejemplo, un módulo central de drupal llamado "nodo" invoca varios ganchos. Uno de ellos es el hook_node_updateque se invoca cada vez que se actualiza un nodo existente. Cuando se invoca este gancho, se llama a la mymoduleimplementación de su módulo (digamos que lo llamamos ) hook_node_update, que en este caso será una función en el archivo .module de su módulo llamado mymodule_node_update(Obviamente esta función puede estar en cualquier archivo en la carpeta de su módulo siempre que está incluido en el archivo .module también). Este gancho también pasará los parámetros necesarios (variables) que puede usar, modificar y / o volver a la función que invoca el gancho.

Cuando comencé a aprender Drupal, estaba en el mismo barco que tú ahora, es un poco difícil de entender al principio, pero una vez que lo obtienes, es tan simple e intuitivo. Buena suerte.


1
Gracias por su respuesta. Me ayuda mucho. Puede que dicen por favor qué es el concepto de arranque en Drupal y cómo son tratados los ganchos en bootstraping en palabras sencillas como se explica respuesta anterior ..
GiLL

@Bayasa, por favor ingrese sus propios pensamientos aquí. Solo estoy agregando el mío. Puedes pensar en impulsar el impulso como iniciar tu computadora. Drupal tiene muchas API, incluidas bases de datos, archivos y formularios. Estos se basan en una "plataforma". Durante el arranque, Drupal define estas funciones y las otras configuraciones (conexión de base de datos, carpetas de archivos, etc.) para que el resto del sistema pueda continuar desde el resto.
AyeshK

32

Uno de los desarrolladores principales escribió un artículo hace un tiempo llamado "Programación Drupal desde una perspectiva orientada a objetos" . Explica bien cómo se puede pensar que los ganchos implementan muchos de los patrones de diseño comunes . La mejor explicación de ganchos proviene del artículo:

El sistema de gancho de Drupal es la base para su abstracción de interfaz. Los ganchos definen las operaciones que se pueden realizar en o por un módulo. Si un módulo implementa un enlace, entra en un contrato para realizar una tarea particular o devolver un tipo particular de información cuando se invoca el enlace. El código de llamada no necesita saber nada sobre el módulo o la forma en que se implementa el gancho para realizar un trabajo útil invocando el gancho.



@chx, gracias. Estoy contemplando eliminar esta respuesta ahora. Lo publiqué b / c. Solía ​​hacer mucho trabajo OO en C simple, y me acostumbré a los conceptos OO sin objetos reales. Sin embargo, tienes razón acerca de la relación punto-corte / tejedor. Sin embargo, no estoy seguro de si la cita es una descripción precisa de un aspecto (ignorando la parte de "abstracción de interfaz").
mpdonadio

21

Bootstrap es el proceso por el que Drupal pasa para construir una página, básicamente ejecutando todo el núcleo, el tema y el código del módulo en orden.
Básicamente es cómo Drupal arranca y se prepara para hacer su trabajo como CMS.

Es inteligente, ya que nos permite colocar ganchos en cualquier parte de nuestros módulos y temas, y el proceso de arranque se asegura de que se ejecuten en el punto correcto.
Por ejemplo, si usa 'hook_form_alter' para agregar una casilla de verificación personalizada a un formulario, el bootstrap de Drupal se asegurará de que ejecute ese código, justo antes de que presente su formulario.

Un problema con el programa de arranque es que todo el proceso tarda en ejecutarse, incluso si solo está devolviendo una pequeña cantidad de datos. Cuando se utiliza Drupal con el módulo de servicios como API y se devuelven muchas pequeñas respuestas XHTML o JSON, ejecutar todo el bootstrap no es muy eficiente. Algunas personas inteligentes están buscando formas inteligentes de evitar esto para Drupal 8.

Pero para renderizar páginas normales de Drupal, el proceso de arranque funciona muy bien, utiliza el sistema de almacenamiento en caché de Drupals para acelerar las cosas y le brinda control total sobre cada parte de su sitio. Si encuentra su sitio lento, siempre puede usar algo como APC o MemCached para ayudar a acelerar las cosas.

Espero que mi respuesta sea precisa y explique las cosas simplemente para ti, no soy un experto, pero creo que así es como funciona.


15

Bootstrap es el proceso durante el cual Drupal se inicializa; el proceso en realidad incluye:

  • Establecer el error y los manejadores de excepciones
  • Inicializar el valor de algunas variables de especificación global contenidas en $_SERVER
  • Inicializando algunas variables con init_set()
  • Encontrar la versión en caché de la página para servir
  • Inicializando la base de datos
  • Configurar los controladores que cargan archivos cuando no se encuentra una clase o una interfaz
  • Inicializando las variables de Drupal
  • Inicializando la sesión PHP
  • Inicializando la variable de lenguaje
  • Cargando los módulos habilitados

Algunas de las operaciones que describí son específicas para Drupal 7 o superior, pero la mayoría de las operaciones son independientes de la versión de Drupal.

Un enlace es una función PHP que se puede llamar desde Drupal o desde módulos de terceros, cuando sea necesario para realizar una tarea. En lugar de tener una lista prefijada de funciones para llamar, la lista se compila comprobando los módulos habilitados y las funciones que implementan.
Por ejemplo, Drupal usa hook_node_update(); cuando un nodo se guarda con node_save () , se ejecuta el siguiente código.

// Call the node specific callback (if any). This can be
// node_invoke($node, 'insert') or
// node_invoke($node, 'update').
node_invoke($node, $op);

Lo que hace node_invoke () es lo siguiente:

  • Obtener la lista de todos los módulos habilitados
  • Comprobar si los módulos habilitados tienen una función cuyo nombre termina en "_node_update" y comienza con el nombre corto del módulo
  • Llamando a esa función, pasando $nodecomo parámetro

Los ganchos pueden guardar sus propios datos en una base de datos o alterar el valor devuelto por una función. El último caso es, por ejemplo, lo que sucede con hook_form_alter () , que altera el valor de $formpasado como referencia a drupal_prepare_form () .

Los ganchos de Drupal generalmente se invocan mediante tres funciones:

drupal_alter()es la función utilizada para invocar enlaces específicos cuyo propósito es alterar los datos que se les pasaron como referencia, como hook_form_alter () , hook_hook_info_alter () y hook_tokens_alter () .

Hay otras funciones que se utilizan para invocar ganchos, como node_invoke(), pero esas funciones utilizan esencialmente una de las funciones que enumeré antes.


12

Los ganchos son puntos de corte y module_invoke_alles el tejedor (por desgracia, no estamos claros en la implementación y hay otras funciones de tejido). Hasta donde yo sé, Drupal es el único sistema que implementa AOP con funciones PHP.

Vea otra explicación sobre ¿Cómo funciona AOP en Drupal?


¿Crees que el artículo de jhodgdon (mencionado en mi respuesta) es correcto?
mpdonadio

2
Ese es el artículo de jonbob de 2005, la atribución es incorrecta. Lo debatiría, sí.

6

Si desea ver los ganchos que Drupal le permite llamar, vaya a api.drupal.org , vaya al cuadro de búsqueda y escriba 'hook_'. Esto le dará una gran lista de la mayoría de los ganchos definidos por Drupal. Haga lo mismo para '_alter' y vea aún más.

La página Ganchos de API de nodo ofrece una lista cronológica de todos los ganchos invocados durante las operaciones de nodo. Puede ver el módulo Node y los sistemas de Entidad y Campo dándose turnos para invocar ganchos.

Por ejemplo, si se desplaza hacia abajo y mira la sección node_load(): El módulo Nodo le dará un hook_load (), y luego pasará el control al sistema de entidad que carga algunos campos. Hay una gran cantidad de ganchos de campo que no figuran en la lista, y luego, cuando termina, el sistema de la entidad invoca hook_entity_load(), antes de pasar el control de vuelta al Nodo que invoca hook_node_load().

Esto le da a su código la oportunidad de actuar en el nodo en cuestión a medida que se carga, pieza por pieza. Aprender estos ganchos y cuándo y por qué se llaman es parte de la aventura de la codificación de Drupal. :-)

Otros sistemas también tienen ganchos. Tales como hook_init()y hook_boot(). Esto llega a la parte inicial de su pregunta. hook_boot()Drupal lo invoca antes de que se cargue el sistema de almacenamiento en caché. Entonces, si su módulo necesita hacer algo antes de que Drupal realmente se haya iniciado, y desea que su código se ejecute independientemente del almacenamiento en caché, entonces lo implementaría hook_boot(). De lo contrario, si solo le interesan las páginas que no están en caché, lo implementaría hook_init().

Esto le da la opción de implementar algo al principio del proceso de carga, antes de que Drupal haya arrancado por completo, al tiempo que le brinda cierta flexibilidad en cuanto a qué punto del proceso desea interceptar.

Si necesita asegurarse de que Drupal haya arrancado hasta cierto punto antes de continuar, puede llamar drupal_bootstrap(). Si hace clic en esa documentación, puede ver los niveles de arranque disponibles, de la nada a todo.

Y, finalmente, puede ver un código ampliamente documentado para cualquier subsistema dado en el proyecto Ejemplos .


El OP está pidiendo una definición de gancho, no una lista de ganchos utilizados por Drupal.
kiamlaluno

6

Los ganchos son funciones php, bloques de construcción basados ​​en las convenciones de nomenclatura "yourmodulename_hookname", están destinados a facilitar la capacidad de los desarrolladores para crear módulos .

Los módulos son reales porque permiten funcionalidades CORE y personalizadas en su sistema Drupal. Por lo tanto, los módulos están hechos de ganchos y cuando se activa un módulo en su instalación de Drupal, sus funciones de ganchos se pueden llamar desde otros módulos gracias a la función module.inc module_invoke_all ($ hook) o module_invoke.

Por lo tanto, para comprender correctamente qué son los ganchos, realmente debe ensuciarse las manos e intentar el desarrollo del módulo. Para este propósito, comience descargando y probando algunos de los ejemplos de Drupal para desarrolladores , también debe familiarizarse con la creación de módulos .

Estos son algunos de los ejemplos útiles de Drupal para desarrolladores mencionados anteriormente:

Ejemplo de implementación hook_block_view () en el módulo block_example

/**
 * @file examples/block_example/block_example.module line 127
 *
 * Implements hook_block_view().
 *
 * This hook generates the contents of the blocks themselves.
 */
function block_example_block_view($delta = '') {
  //The $delta parameter tells us which block is being requested.
  switch ($delta) {
    case 'example_configurable_text':
      // The subject is displayed at the top of the block. Note that it
      // should be passed through t() for translation. The title configured
      // for the block using Drupal UI supercedes this one.
      $block['subject'] = t('Title of first block (example_configurable_text)');

Este gancho le da acceso a la creación de bloques de Drupal para mostrar bloques personalizados en su sitio web. Es posible porque block.module tiene una función _block_render_block que permite a todos los módulos definir su vista hook_block (observe que el módulo_invoca la última línea):

/**
 * @file modules/block/block.module, line 838
 *
 * Render the content and subject for a set of blocks.
 *
 * @param $region_blocks
 *   An array of block objects such as returned for one region by _block_load_blocks().
 *
 * @return
 *   An array of visible blocks as expected by drupal_render().
 */
function _block_render_blocks($region_blocks) {
  ...
  foreach ($region_blocks as $key => $block) {
    ...
    $array = module_invoke($block->module, 'block_view', $block->delta);

Ejemplo de implementación hook_menu () en el módulo render_example

/**
 * @file examples/render_example/render_example.module line 22
 * 
 * Implements hook_menu().
 */
function render_example_menu() {
  ...
  $items['examples/render_example/arrays'] = array(
    'title' => 'Render array examples',
    'page callback' => 'render_example_arrays',
    'access callback' => TRUE,
  );

Este enlace está vinculado al sistema de enrutamiento de url de Drupal y define los patrones de url con las devoluciones de llamada de renderización asociadas utilizadas por su módulo. Se invoca desde system.module .

Sobre el bootstrap, básicamente, solo necesita saber que se ejecuta en cada solicitud de página. Realmente te recomiendo que leas esta respuesta de stackoverflow , explica cómo los bootstrap y los ganchos están relacionados pero separados.

Con respecto a la visualización de la página web, la visualización html del sitio web de Drupal se logra principalmente con conjuntos de renderizado y temas.


3

En cualquier lugar donde un módulo llame a module_implements () http://api.drupal.org/api/drupal/includes%21module.inc/function/module_implements/7 Drupal activará todas las funciones correctamente nombradas en el orden correcto en función de su peso. Estas se denominan funciones de enlace porque en la documentación de los módulos que usan módulos_implementos se ven cosas como hook_menu (para cuando el menú llama a todas las funciones diseñadas para devolver elementos del menú). La palabra "gancho" solo necesita ser reemplazada por el nombre del módulo que lo implementa y Drupal hace el resto.

También hay una función drupal_alter () que activa todas las funciones de alteración correctamente nombradas, con la intención de permitirle alterar cosas que fueron previamente registradas por otro enlace.

En general, los alter pasarán argumentos por referencia para que pueda editar el objeto directamente, mientras que los ganchos "normales" generalmente le permiten devolver cosas nuevas.

La idea es que cualquier módulo (incluido el suyo) se puede ampliar fácilmente pidiéndole a Drupal que llame a todas las funciones de enlace requeridas y recupere lo que devuelven para ser procesado. El módulo que llama a las funciones de enlace no necesita saber nada acerca de los módulos que implementan los enlaces, y los módulos que implementan el enlace realmente no necesitan saber nada sobre el módulo que llama al enlace. Lo único que ambos módulos deben saber es la estructura de los datos que se devuelven o alteran.

En la práctica, los ganchos se usan generalmente para:

  • responder a eventos, como se llama a hook_user_login cuando un usuario inicia sesión
  • registrar algo nuevo que pueda usarse para extender el sistema como hook_menu
  • tema / renderizar html o construir / validar / enviar formularios

1

Tiene muchas respuestas arriba, pero quiero dar una respuesta de una manera mucho más simple para comprender el concepto muy básico detrás de los ganchos. Los ganchos están realmente integrados en funciones en drupal core para administrar diferentes cosas y realizan diferentes trabajos en core, puede sincronizar sus propias funciones con estas funciones integradas de drupal core para agregar su funcionalidad en sus propias funciones llamando a diferentes ganchos.

¡Espero que entiendas el punto!


1

Para mí, se trata de la función module_implements cuando se trata de ganchos y núcleo (D7). Una cosa que creo que es crucial de entender es que al escribir un gancho para modificar algo, de ninguna manera tienes la última palabra en lo que sucede con las estructuras de datos con las que estás tratando. Su gancho simplemente se pone en la línea (cola) de funciones que TAMBIÉN actúan sobre las mismas estructuras de datos, ya sean menús, enlaces de menú, bloques, nodos, usuarios o cualquier entidad o elemento de representación.

Por lo tanto, para ver realmente cómo se utilizan sus ganchos de la manera esperada, necesita saber o estar al tanto de dónde se encuentra (su gancho) en la cola. Esto está determinado por el peso de su módulo. El núcleo de Drupal simplemente llama a los ganchos correctamente nombrados en el orden de peso ascendente y sucede lo que suceda con los datos.

He escrito ganchos antes que eso no tuvo ningún efecto, solo para aprender después de horas de headbanging que el peso de mi módulo era demasiado liviano y que los ganchos subsiguientes estaban efectivamente haciendo lo que hice o haciendo caso omiso de todo.

Un gancho bien escrito no se "manipulará" ni "forzará" a ser el último, sino que se "colocará bien con los demás" asegurándose de que mantengan las estructuras de datos como lo espera el resto de los ganchos en la línea.

Y hablando de "La línea" de ganchos. A lo largo de los años, he buscado en Google cosas de Drupal, esta imagen parece ser una buena representación de la lista de posibilidades de preprocesos y procesos.
ingrese la descripción de la imagen aquí


1

De manera mucho más simple, los ganchos ayudan al desarrollador a alterar la funcionalidad existente de acuerdo con los requisitos sin realizar cambios en el código existente. Más como Función abstracta en php.

Ejemplo: ha creado un módulo para reservar un boleto de autobús. De acuerdo con su código, si el boleto se reserva una vez, la ubicación de recogida no es editable, que era su requisito para ese proyecto. Suponga que su amigo necesita el mismo módulo para un requisito similar, con la excepción de que el usuario puede cambiar la ubicación de recogida. De alguna manera, tiene que usar su módulo y no quiere que haga ningún cambio de código. Entonces, usted proporciona una interfaz (enlace en nuestro caso) donde él podría implementar sus cambios sin hacer cambios en su módulo.

En drupal hasta drupal-7 tenemos ganchos para módulos y temas. Para saber cómo funciona el gancho, consulte drupal.org ganchos para crear un gancho personalizado, consulte este enlace


0

Manos. Permitir que los módulos interactúen con el núcleo de Drupal. El sistema de módulos de Drupal se basa en el concepto de "ganchos". Un gancho es una función PHP que se llama foo_bar (), donde "foo" es el nombre del módulo (cuyo nombre de archivo es foo.module) y "bar" es el nombre del gancho.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.