Статьи

Drupal становится социальным: создание модуля «Нравится» в Drupal

В этой статье мы рассмотрим, как мы можем создать модуль Drupal, который позволит вашим пользователям нравиться ваши сообщения. Реализация будет использовать jQuery для выполнения вызовов AJAX и асинхронного сохранения этих данных.

logo_drupal

Создание вашего Drupal-подобного модуля

Давайте начнем с создания нового модуля Drupal. Для этого сначала нужно создать папку с названием likepost в likepost sites\all\modules\custom вашей установки Drupal, как показано ниже:

Initial folder structure

Внутри этой папки вы должны создать файл с именем likepost.info со следующим содержимым:

 name = likepost description = This module allows the user to like posts in Drupal. core = 7.x 

Этот файл отвечает за предоставление метаданных о вашем модуле. Это позволяет Drupal обнаруживать и загружать его содержимое.

Затем вы должны создать файл с именем likepost.module в той же директории. После создания файла добавьте в него следующий код:

 /** * @file * This is the main module file. */ /** * Implements hook_help(). */ function likepost_help($path, $arg) { if ($path == 'admin/help#likepost') { $output = '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('This module allows the user to like posts in Drupal.') . '</p>'; return $output; } } 

После того, как вы это сделаете, вы можете перейти к разделу модулей в вашем администрировании Drupal и увидеть новый модуль. Пока не включайте модуль, так как мы сделаем это после добавления дополнительных функций.

Создание схемы

likepost.install файл модуля, вы можете создать файл likepost.install внутри корневой папки модуля. Внутри вы определите схему таблицы, которая необходима для хранения лайков в каждом посте для каждого пользователя. Добавьте следующий код в файл:

 <?php /** * Implements hook_schema(). */ function likepost_schema() { $schema['likepost_table_for_likes'] = array( 'description' => t('Add the likes of the user for a post.'), 'fields' => array( 'userid' => array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => t('The user id.'), ), 'nodeid' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => t('The id of the node.'), ), ), 'primary key' => array('userid', 'nodeid'), ); return $schema; } 

В приведенном выше коде мы реализуем hook_schema () , чтобы определить схему для нашей таблицы. Таблицы, которые определены в этом хуке, создаются во время установки модуля и удаляются во время удаления.

Мы определили таблицу с именем likepost_table_for_likes с двумя полями: userid и nodeid . Они оба являются целыми числами и будут хранить одну запись для каждой комбинации ID пользователя и узла, когда пользователю нравится публикация.

После добавления этого файла вы можете установить модуль. Если все прошло правильно, ваш модуль должен быть включен без ошибок, и в вашей базе данных должна быть создана таблица likepost_table_for_likes . Вы также должны увидеть ссылку справки, включенную в списке модулей рядом с вашим модулем likepost . Если вы нажмете на hook_help() , вы сможете увидеть сообщение справки, которое вы определили в реализации hook_help() .

Help Message

Создание обратного вызова в меню для обработки лайков

После того, как мы включили модуль, мы можем добавить обратный вызов меню, который будет обрабатывать AJAX-запрос на добавление или удаление подобного . Для этого добавьте следующий код в ваш файл likepost.module

 /** * Implements hook_menu(). */ function likepost_menu() { $items['likepost/like/%'] = array( 'title' => 'Like', 'page callback' => 'likepost_like', 'page arguments' => array(2), 'access arguments' => array('access content'), 'type' => MENU_SUGGESTED_ITEM, ); return $items; } function likepost_like($nodeid) { $nodeid = (int)$nodeid; global $user; $like = likepost_get_like($nodeid, $user->uid); if ($like !== 0) { db_delete('likepost_table_for_likes') ->condition('userid', $user->uid) ->condition('nodeid', $nodeid) ->execute(); //Update the like value , which will be sent as response $like = 0; } else { db_insert('likepost_table_for_likes') ->fields(array( 'userid' => $user->uid, 'nodeid' => $nodeid )) ->execute(); //Update the like value , which will be sent as response $like = 1; } $total_count = likepost_get_total_like($nodeid); drupal_json_output(array( 'like_status' => $like, 'total_count' => $total_count ) ); } /** * Return the total like count for a node. */ function likepost_get_total_like($nid) { $total_count = db_query('SELECT count(*) from {likepost_table_for_likes} where nodeid = :nodeid', array(':nodeid' => $nid))->fetchField(); return (int)$total_count; } /** * Return whether the current user has liked the node. */ function likepost_get_like($nodeid, $userid) { $like = db_query('SELECT count(*) FROM {likepost_table_for_likes} WHERE nodeid = :nodeid AND userid = :userid', array(':nodeid' => $nodeid, ':userid' => $userid))->fetchField(); return (int)$like; } 

В приведенном выше коде мы реализуем hook_menu () так, чтобы всякий раз, когда к пути likepost/like обращались с идентификатором узла, он вызывал функцию likepost_like() .

Внутри likepost_like() мы получаем идентификатор узла и идентификатор зарегистрированного пользователя и передаем их в функцию likepost_get_like() . В функции likepost_get_like() мы проверяем нашу таблицу likepost_table_for_likes чтобы увидеть, понравился ли этому пользователю этот пост. В случае, если у него есть, мы удалим это как, в противном случае мы вставим запись. Как только это будет сделано, мы вызываем likepost_get_total_like() с идентификатором узла в качестве параметра, который вычисляет общее количество лайков от всех пользователей в этом посте. Эти значения затем возвращаются как JSON с помощью API-функции drupal_json_output() .

Этот обратный вызов меню будет вызван из нашего вызова JQuery AJAX и обновит пользовательский интерфейс с помощью JSON, который он получает.

Отображение кнопки «Мне нравится» на узле

После того, как мы создали обратный вызов, нам нужно показать аналогичную ссылку на каждом из постов. Мы можем сделать это, реализовав hook_node_view() как hook_node_view() ниже:

 /** * Implementation of hook_node_view */ function likepost_node_view($node, $view_mode) { if ($view_mode == 'full'){ $node->content['likepost_display'] = array('#markup' => display_like_post_details($node->nid),'#weight' => 100); $node->content['#attached']['js'][] = array('data' => drupal_get_path('module', 'likepost') .'/likepost.js'); $node->content['#attached']['css'][] = array('data' => drupal_get_path('module', 'likepost') .'/likepost.css'); } } /** * Displays the Like post details. */ function display_like_post_details($nid) { global $user; $totalLike = likepost_get_total_like($nid); $hasCurrentUserLiked = likepost_get_like($nid , $user->uid); return theme('like_post',array('nid' =>$nid, 'totalLike' =>$totalLike, 'hasCurrentUserLiked' => $hasCurrentUserLiked)); } /** * Implements hook_theme(). */ function likepost_theme() { $themes = array ( 'like_post' => array( 'arguments' => array('nid','totalLike','hasCurrentUserLiked'), ), ); return $themes; } function theme_like_post($arguments) { $nid = $arguments['nid']; $totalLike = $arguments['totalLike']; $hasCurrentUserLiked = $arguments['hasCurrentUserLiked']; global $base_url; $output = '<div class="likepost">'; $output .= 'Total number of likes on the post are '; $output .= '<div class="total_count">'.$totalLike.'</div>'; if($hasCurrentUserLiked == 0) { $linkText = 'Like'; } else { $linkText = 'Delete Like'; } $output .= l($linkText, $base_url.'/likepost/like/'.$nid, array('attributes' => array('class' => 'like-link'))); $output .= '</div>'; return $output; } 

Внутри likepost_node_view() мы проверяем, когда узел находится в режиме full просмотра, и добавляем разметку, возвращаемую функцией display_like_post_details() . Мы также прикрепили наш пользовательский файл JS и CSS, когда представление отображается с использованием свойства присоединенного к содержимому узла. В функции display_like_post_details() мы получаем общее количество лайков для поста и то, понравился или нет этот пост текущему пользователю. Затем мы вызываем функцию theme, которая будет вызывать функцию theme_like_post() которую мы объявили в реализации hook_theme, но которая позволит дизайнерам переопределять их при необходимости. В theme_like_post() мы создаем вывод HTML соответственно. Ссылка на ссылку — это $base_url и к ней добавлен путь к нашему $base_url . Идентификатор узла также прикрепляется к URL-адресу, который будет передан в качестве параметра для обратного вызова.

Как только это будет сделано, добавьте файл likepost.css в корневую папку модуля со следующим содержимым:

 .likepost { border-style: dotted; border-color: #98bf21; padding: 10px; } .total_count { font-weight: bold; } .like-link { color:red; } .like-link:hover { color: red; } 

Теперь, если вы перейдете на полную страницу поста, вы увидите количество лайков, как показано ниже.

Добавление логики jQuery

Теперь, когда мы видим ссылку « likepost.js нравится», нам просто нужно создать файл likepost.js со следующим содержимым:

 jQuery(document).ready(function () { jQuery('a.like-link').click(function () { jQuery.ajax({ type: 'POST', url: this.href, dataType: 'json', success: function (data) { if(data.like_status == 0) { jQuery('a.like-link').html('Like'); } else { jQuery('a.like-link').html('Delete Like'); } jQuery('.total_count').html(data.total_count); }, data: 'js=1' }); return false; }); }); 

Приведенный выше код связывает событие click со ссылкой like и выполняет AJAX-запрос к URL-адресу нашей функции меню обратного вызова. Последний соответствующим образом обновит счетчик похожих записей, а затем вернет новый общий счетчик и аналогичное состояние, которое используется в функции успеха вызова AJAX для обновления пользовательского интерфейса.

Updated UI with Like count

Вывод

jQuery и AJAX — мощные инструменты для создания динамичных и адаптивных веб-сайтов. Вы можете легко использовать их в своих модулях Drupal для добавления функциональности на свой сайт Drupal, поскольку Drupal уже использует jQuery для своего интерфейса.

Есть отзывы? Дайте нам знать об этом в комментариях!