Skip to content

Commit

Permalink
Implement Reader App on Route "/reader"
Browse files Browse the repository at this point in the history
The `/reader` route now passes either the `identifier` or `orderId` parameters to the `Reader` React app.

This was implemented to ensure the proper loading of external scripts that require a full page reload.
  • Loading branch information
kasperbirch1 committed Dec 6, 2024
1 parent 6b170e7 commit fe5b354
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 2 deletions.
12 changes: 12 additions & 0 deletions web/modules/custom/dpl_react/dpl_react.libraries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ recommendation:
- dpl_react/base
- dpl_react/handler

reader:
remote: https://github.com/danskernesdigitalebibliotek/dpl-react
license:
name: GNU AFFERO
url: https://github.com/danskernesdigitalebibliotek/dpl-react/blob/master/LICENSE
gpl-compatible: true
js:
/libraries/dpl-react/Reader.js: {}
dependencies:
- dpl_react/base
- dpl_react/handler

opening-hours:
remote: https://github.com/danskernesdigitalebibliotek/dpl-react
license:
Expand Down
9 changes: 9 additions & 0 deletions web/modules/custom/dpl_react_apps/dpl_react_apps.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@ dpl_react_apps.work:
_controller: '\Drupal\dpl_react_apps\Controller\DplReactAppsController::work'
requirements:
_permission: 'access content'

dpl_react_apps.reader:
path: '/reader'
defaults:
_controller: '\Drupal\dpl_react_apps\Controller\DplReactAppsController::reader'
requirements:
_permission: 'access content'
options:
no_cache: true
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Drupal\dpl_react_apps\Controller;

use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Drupal\dpl_fbs\Form\FbsSettingsForm;
Expand All @@ -13,8 +14,10 @@
use Drupal\dpl_library_agency\GeneralSettings;
use Drupal\dpl_library_agency\ReservationSettings;
use Symfony\Component\DependencyInjection\ContainerInterface;
use function Safe\json_encode as json_encode;
use function Safe\preg_replace as preg_replace;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use function Safe\json_encode;
use function Safe\preg_replace;

/**
* Controller for rendering full page DPL React apps.
Expand All @@ -31,6 +34,7 @@ public function __construct(
protected BranchRepositoryInterface $branchRepository,
protected DplInstantLoanSettings $instantLoanSettings,
protected GeneralSettings $generalSettings,
protected BlockManagerInterface $blockManager,
) {}

/**
Expand All @@ -49,6 +53,7 @@ public static function create(ContainerInterface $container) {
$container->get('dpl_library_agency.branch.repository'),
$container->get('dpl_instant_loan.settings'),
$container->get('dpl_library_agency.general_settings'),
$container->get('plugin.manager.block'),
);
}

Expand Down Expand Up @@ -502,4 +507,39 @@ public static function externalApiBaseUrls(): array {
return $urls;
}

/**
* Render the Reader React app.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The HTTP request containing query parameters.
*
* @return mixed[]
* Render array with the Reader app block.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
public function reader(Request $request): array {

$identifier = $request->query->get('identifier');
$orderId = $request->query->get('orderId');

if (!$identifier && !$orderId) {
throw new \InvalidArgumentException('Either identifier or orderId must be provided.');
}

/** @var \Drupal\dpl_react_apps\Plugin\Block\ReaderAppBlock $plugin_block */
$plugin_block = $this->blockManager->createInstance('reader_app_block', [
'identifier' => $identifier,
'orderId' => $orderId,
]);

// Access check for the block.
$access_result = $plugin_block->access($this->currentUser());
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
throw new AccessDeniedHttpException();
}

return $plugin_block->build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Drupal\dpl_react_apps\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Provides a block for the Reader React app.
*
* @Block(
* id = "reader_app_block",
* admin_label = "Reader App"
* )
*/
class ReaderAppBlock extends BlockBase implements ContainerFactoryPluginInterface {

/**
* A unique identifier for the Reader resource.
*
* @var string
*/
protected string $identifier;

/**
* ReaderAppBlock constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
*/
public function __construct(array $configuration, string $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);

// Assign the identifier from the configuration if available.
if (isset($configuration['identifier'])) {
$this->identifier = $configuration['identifier'];
}
else {
// Default to an empty string if not provided.
$this->identifier = 'Default';
}
}

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition);
}

/**
* {@inheritDoc}
*
* @return mixed[]
* Render array for the Reader app.
*/
public function build(): array {
$data = [
'identifier' => $this->identifier ?? NULL,
'orderId' => $this->orderId ?? NULL,
];

return [
'#theme' => 'dpl_react_app',
'#name' => 'reader',
'#data' => $data,
];
}

}
54 changes: 54 additions & 0 deletions web/themes/custom/novel/templates/layout/page--reader.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{#
/**
* @file
* Theme override to display a /reader page.
*
* This template is a variant of the page.html.twig template used for rendering
* the user registration page. As we don't want the user accessing things outside
* of the registration form, we have removed the header and footer regions for this
* page.
*
* Available variables:
*
* General utility variables:
* - base_path: The base URL path of the Drupal installation. Will usually be
* "/" unless you have installed Drupal in a sub-directory.
* - is_front: A flag indicating if the current page is the front page.
* - logged_in: A flag indicating if the user is registered and signed in.
* - is_admin: A flag indicating if the user has permission to access
* administration pages.
*
* Site identity:
* - front_page: The URL of the front page. Use this instead of base_path when
* linking to the front page. This includes the language domain or prefix.
*
* Page content (in order of occurrence in the default page.html.twig):
* - node: Fully loaded node, if there is an automatically-loaded node
* associated with the page and the node ID is the second argument in the
* page's path (e.g. node/12345 and node/12345/revisions, but not
* comment/reply/12345).
*
* Regions:
* - page.header: Items for the header region.
* - page.primary_menu: Items for the primary menu region.
* - page.secondary_menu: Items for the secondary menu region.
* - page.highlighted: Items for the highlighted content region.
* - page.help: Dynamic help text, mostly for admin pages.
* - page.content: The main content of the current page.
* - page.sidebar_first: Items for the first sidebar.
* - page.sidebar_second: Items for the second sidebar.
* - page.footer: Items for the footer region.
* - page.breadcrumb: Items for the breadcrumb region.
*
* @see template_preprocess_page()
* @see html.html.twig
*/
#}

<div>
{{ drupal_block('system_messages_block') }}

<main id="main-content" role="main">
{{ page.content }}
</main>
</div>

0 comments on commit fe5b354

Please sign in to comment.