Commit d5622e17 by Manzar Hussain

nexpre

parent 3d63e138
NEXT PREVIOUS POST BLOCK
---------------------------
INTRODUCTION
-----------
Offering NEXT PREVIOUS POST BLOCK without going to the listing page.
INSTALLATION:
-------------
1. Install as you would normally install a contributed Drupal module.
See: https://www.drupal.org/node/895232 for further information.
REQUIREMENTS
------------
The basic nextpre module has node dependencies, nothing special is required.
CONFIGURATION
-------------
1. Install module “Next and previous link”.
2. Go to the “Block Layout”. Eg:- Admin Menu >> structure >> block layout
3. Go to the your block region.
4. Click the "Place block" button and in the modal dialog click the
"Place block" button next to "Next Previous link".
5. On the block configuration form you can choose the node bundle name to
filter and the next/previous labels the buttons will have.
UNINSTALLATION
--------------
1. Uninstall as you would normally Uninstall a contributed Drupal module.
See: https://www.drupal.org/docs/user_guide/en/config-uninstall.html
for further information.
UI INFORMATION
--------------
1. For the UI, the Developer will add the class in both buttons
during block configuration.
{
"name": "drupal/nextpre",
"description": "Next and previous link on detail page",
"type": "drupal-module",
"authors": [
{
"name": "Rohit Rajput (rohit-drupal)",
"homepage": "https://www.drupal.org/u/rohit-drupal",
"role": "Maintainer"
}
]
}
name: Next And Previous Link
type: module
description: Next and previous link on detail page.
core: 8.x
core_version_requirement: ^8 || ^9
dependencies:
- drupal:node
# Information added by Drupal.org packaging script on 2020-10-12
version: '9.0.1'
project: 'nextpre'
datestamp: 1602505206
<?php
/**
* @file
* Primary module hooks for Nextpre module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function nextpre_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.nextpre':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Next and previous link module will allow the website visitors to jump on the next or previous post without going back to the main page to see all the posts. Drupal developers can use this module for particular content types. Suppose, there are many large content bundles, then the developer can apply the module for a specific bunch of content.') . '</p>';
$output .= '<h3>' . t('Configuration') . '</h3>';
$output .= '<ol>
<li>Install module “Next and previous link”</li>
<li>Go to the “Block Layout”. Eg:- Admin Menu >> structure >> block layout</li>
<li>Go to the your block region.</li>
<li>Click the "Place block" button and in the modal dialog click the
"Place block" button next to "Next Previous link".</li>
<li>On the block configuration form you can choose the node bundle name to
filter and the next/previous labels the buttons will have.</li>
</ol>';
$output .= '<h3>' . t('For example') . '</h3>';
$output .= '<p>' . t('I have a "Blog" content type and in this blog 100 pages (Nodes). A visitor comes on the website and read blog number 56 (Node/56). We have to provide a next and previous link on the detail page to jump the next and previous blog.') . '</p>';
return $output;
}
}
<?php
namespace Drupal\nextpre\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Provides a 'Next Previous' block.
*
* @Block(
* id = "next_previous_block",
* admin_label = @Translation("Next Previous link"),
* category = @Translation("Blocks")
* )
*/
class NextPreviousBlock extends BlockBase implements BlockPluginInterface, ContainerFactoryPluginInterface {
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Creates a NextPreviousBlock instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match, EntityTypeManagerInterface $entityTypeManager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->routeMatch = $route_match;
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_route_match'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$node_types = node_type_get_names();
$form['content_type'] = [
'#type' => 'select',
'#title' => $this->t('Content Types'),
'#empty_option' => $this->t('-None-'),
'#options' => $node_types,
'#default_value' => isset($this->configuration['content_type']) ? $this->configuration['content_type'] : '',
'#required' => TRUE,
];
$form['previous_text'] = [
'#type' => 'textfield',
'#title' => $this->t('Previous text'),
'#description' => $this->t('Add your previous button name'),
'#default_value' => isset($this->configuration['previous_text']) ? $this->configuration['previous_text'] : '',
'#required' => TRUE,
];
$form['next_text'] = [
'#type' => 'textfield',
'#title' => $this->t('Next text'),
'#description' => $this->t('Add your next button name'),
'#default_value' => isset($this->configuration['next_text']) ? $this->configuration['next_text'] : '',
'#required' => TRUE,
];
$form['previouslink_class'] = [
'#type' => 'textfield',
'#title' => $this->t('Previous link class'),
'#description' => $this->t('Add your class in previous link'),
'#default_value' => isset($this->configuration['previouslink_class']) ? $this->configuration['previouslink_class'] : '',
];
$form['nextlink_class'] = [
'#type' => 'textfield',
'#title' => $this->t('Next link class'),
'#description' => $this->t('Add your class in next link'),
'#default_value' => isset($this->configuration['nextlink_class']) ? $this->configuration['nextlink_class'] : '',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$this->configuration['content_type'] = $form_state->getValue('content_type');
$this->configuration['previous_text'] = $values['previous_text'];
$this->configuration['next_text'] = $values['next_text'];
$this->configuration['previouslink_class'] = $values['previouslink_class'];
$this->configuration['nextlink_class'] = $values['nextlink_class'];
}
/**
* {@inheritdoc}
*/
public function build() {
$link = [];
// Get the created time of the current node.
$node = $this->routeMatch->getParameter('node');
if ($node instanceof NodeInterface && $node->getType() == $this->configuration['content_type']) {
$current_nid = $node->id();
$prev = $this->generatePrevious($node);
if (!empty($prev)) {
$link['prev'] = $prev;
}
$next = $this->generateNext($node);
if (!empty($next)) {
$link['next'] = $next;
}
}
return $link;
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
// Get the created time of the current node.
$node = $this->routeMatch->getParameter('node');
if (!empty($node) && $node instanceof NodeInterface) {
// If there is node add its cachetag.
return Cache::mergeTags(parent::getCacheTags(), ['node:*']);
}
else {
// Return default tags instead.
return parent::getCacheTags();
}
}
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return Cache::mergeContexts(parent::getCacheContexts(), ['route']);
}
/**
* Lookup the previous node,youngest node which is still older than the node.
*
* @param string $current_nid
* Show current page node id.
*
* @return array
* A render array for a previous node.
*/
private function generatePrevious($node) {
return $this->generateNextPrevious($node, 'prev');
}
/**
* Lookup the next node,oldest node which is still younger than the node.
*
* @param string $current_nid
* Show current page node id.
*
* @return array
* A render array for a next node.
*/
private function generateNext($node) {
return $this->generateNextPrevious($node, 'next');
}
const DIRECTION__NEXT = 'next';
/**
* Lookup the next or previous node.
*
* @param string $current_nid
* Get current page node id.
* @param string $direction
* Default value is "next" and other value come from
* generatePrevious() and generatePrevious().
*
* @return array
* Find the alias of the next node.
*/
private function generateNextPrevious($node, $direction = self::DIRECTION__NEXT) {
$comparison_opperator = '>';
$sort = 'ASC';
$display_text = $this->configuration['next_text'];
$class = $this->configuration['nextlink_class'] ? $this->configuration['nextlink_class'] : 'btn';
$current_nid = $node->id();
$current_langcode = $node->get('langcode')->value;
if ($direction === 'prev') {
$comparison_opperator = '<';
$sort = 'DESC';
$display_text = $this->configuration['previous_text'];
$class = $this->configuration['previouslink_class'] ? $this->configuration['previouslink_class'] : 'btn';
}
// Lookup 1 node younger (or older) than the current node.
$query = $this->entityTypeManager->getStorage('node');
$query_result = $query->getQuery();
$next = $query_result->condition('nid', $current_nid, $comparison_opperator)
->condition('type', $this->configuration['content_type'])
->condition('status', 1)
->condition('langcode', $current_langcode)
->sort('nid', $sort)
->range(0, 1)
->execute();
// If this is not the youngest (or oldest) node.
if (!empty($next) && is_array($next)) {
$next = array_values($next);
$next = $next[0];
// Find the alias of the next node.
$nid = $next;
$url = Url::fromRoute('entity.node.canonical', ['node' => $nid], []);
$link = Link::fromTextAndUrl($display_text, Url::fromUri('internal:/' . $url->getInternalPath()));
$link = $link->toRenderable();
$link['#attributes'] = ['class' => ['nextpre__btn', $class]];
return $link;
}
return '';
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment