Browse Source

Add Entity Reference and Inline Entity Form support.

fix
Alexander O'Neill 6 years ago
parent
commit
fdde2b0cd2
  1. 32
      README.md
  2. 1
      bibcite_footnotes.info.yml
  3. 10
      bibcite_footnotes.libraries.yml
  4. 106
      bibcite_footnotes.module
  5. 18
      js/plugins/reference_footnotes/dialogs/footnotes.js
  6. 28
      js/replace_citations.js
  7. 23
      src/Plugin/CKEditorPlugin/ReferenceFootnotes.php
  8. 10
      src/Plugin/Filter/ReferenceFootnotesFilter.php

32
README.md

@ -12,12 +12,9 @@ Contents
Introduction
------------
A plugin for the Footnotes module (https://www.drupal.org/project/footnotes)
that lets a user insert references created or importeed using the Bibliography
and Citation project (https://www.drupal.org/project/bibcite).
Provides a CKEditor plugin that lets a user select from a list of citations which
appear in a formatted at the bottom of the text area that contains the footnote.
appear in a formatted list at the bottom of the text area that contains endnotes
and references.
Installation
------------
@ -34,6 +31,13 @@ you will need to add the following HTML tags for the reference footnotes to disp
Configuration
-------------
Add a field to a node type that is an Entity Reference field pointing to
Bibcite Reference entities.
Go to Admin -> Configuration -> Content Authoring -> Text Formats and Editors.
Edit a Rich text format that will include reference footnotes.
Drag the Reference Footnotes button into the active set of buttons in the text format
you want to use References in and save the settings.
@ -41,7 +45,25 @@ You will then need to create or import one or more references using the Bibliogr
Citations project. Those will then appear in a select list when you are editing a text area
and click on the Reference Footnote button.
Optionally you can install Inline Entity Form which allowes a user to
create new references directly in the node edit form.
Adding References to Content
----------------------------
If not using the inline entity form, select the references that appear in the
list of referenced Bibcite reference types that should be available to the editor,
ten save the node.
When you edit the node again, and you click on the Reference Footnote button,
a list of citaitons will be available to choose from.
Current Maintainers
-------------------
* Alexander O'Neill (https://www.drupal.org/u/alxp)
Sponsors
--------
* This work is supported by the [University of Prince Edward Island Robertson Librrary](https://library.upei.ca).

1
bibcite_footnotes.info.yml

@ -6,4 +6,5 @@ package: 'Bibliography & Citation'
dependencies:
- bibcite:bibcite
- bibcite:bibcite_entity
- core:entity_reference
- footnotes:footnotes

10
bibcite_footnotes.libraries.yml

@ -3,3 +3,13 @@ reference_footnote:
css:
theme:
css/reference_footnote.css: {}
dependencies:
- core/jquery
- core/drupalSettings
replace_citations:
version: VERSION
js:
js/replace_citations.js: {}
dependencies:
- core/jquery
- core/drupalSettings

106
bibcite_footnotes.module

@ -5,12 +5,14 @@
* Contains bibcite_footnotes.module.
*/
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\bibcite_footnotes\CitationTools;
use Drupal\bibcite_footnotes\Plugin\Filter\ReferenceFootnotesFilter;
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_theme().
@ -207,3 +209,107 @@ function bibcite_footnotes_preprocess_bibcite_footnote_link(&$variables) {
$variables['fn']['fn'] = $link;
// $variables['fn']['fn'][] = $link;
}
/**
* Implementation of hook_inline_entity_form_entity_form_alter().
*
* Force all entities to be saved once they are created.
*
* @TODO: Add cleanup batch task for orphaned References.
*
* @param $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
function bibcite_footnotes_inline_entity_form_entity_form_alter(&$form, FormStateInterface &$form_state) {
$form['#save_entity'] = TRUE;
}
/**
* Implementation of hook_form_node_form_alter().
*
* This function populates the Reference list drop-down in the CKEditor drop-down.
* It gathers all referenced entities of type bibcite_reference and puts them
* into a JavaScript setting under drupalSettings.bibcite_footnotes.references.
*
* @param $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
function bibcite_footnotes_form_node_form_alter(&$form, FormStateInterface &$form_state) {
$ief = $form_state->get('inline_entity_form');
if ($ief) {
// Inline entity storage uses hashes to separate out the field instances.
$bibcite_references = [];
foreach ($ief as $ief_instance) {
/**
* @var FieldConfig $field_config
*/
$field_config = $ief_instance['instance'];
// Check if this is a bibcite_reference field type.
if ($field_config->getSetting('handler') == 'default:bibcite_reference') {
$field_name = $field_config->get('field_name');
if (!empty($ief_instance['entities'])) {
foreach ($ief_instance['entities'] as $entity_wrapper) {
/**
* @var \Drupal\core\Entity\EntityInterface $entity
*/
$entity = $entity_wrapper['entity'];
if ($entity->getEntityTypeId() == 'bibcite_reference') {
list($citation_text, $citation_key) = bibcite_footnotes_get_ckeditor_select_item($entity);
$bibcite_references[] = [$citation_text, $citation_key];
}
}
}
}
}
$triggering_element = $form_state->getTriggeringElement();
if (!$triggering_element) {
$form['#attached']['drupalSettings']['bibcite_footnotes']['references'] = $bibcite_references;
}
else {
$form[$triggering_element['#parents'][0]]['widget']['#attached']['library'][] = 'bibcite_footnotes/replace_citations';
$form[$triggering_element['#parents'][0]]['widget']['#attached']['drupalSettings']['bibcite_footnotes']['references'] = $bibcite_references;
}
}
else {
// Not using Inline Entity Form, get the references if they exist
$entity = $form_state->getFormObject()->getEntity();
$fields = $entity->getFields();
$reference_field = FALSE;
foreach ($fields as $field) {
$type = $field->getFieldDefinition();
if ($type->getType() == 'entity_reference') {
if ($type->getSetting('handler') == 'default:bibcite_reference') {
$referenced_entities = $field->referencedEntities();
$bibcite_references = [];
foreach ($referenced_entities as $referenced_entity) {
list($citation_text, $citation_key) = bibcite_footnotes_get_ckeditor_select_item($referenced_entity);
$bibcite_references[] = [$citation_text, $citation_key];
}
$form['#attached']['drupalSettings']['bibcite_footnotes']['references'] = $bibcite_references;
}
}
}
}
}
/**
* Construct an item to go into the CKEditor Reference drop-down list.
*
* @param $entity
*
* @return array
* The form of the array is ["Citation string", [reference entity id].
*/
function bibcite_footnotes_get_ckeditor_select_item($entity): array {
$serializer = \Drupal::service('serializer');
$data = $serializer->normalize($entity, 'csl');
$build = ['#theme' => 'bibcite_citation', '#data' => $data];
$citation_text = trim(strip_tags(render($build)));
// Attempt to match up pre-saved entities with the eventual saved ones.
$citation_key = $entity->id->first()->getValue()['value'];
return [$citation_text, $citation_key];
}

18
js/plugins/reference_footnotes/dialogs/footnotes.js

@ -14,7 +14,7 @@
{
id: 'reference',
type: 'select',
items: editor.config.referenceFootnotes_list,
items: [[" - None - ", 0]].concat(drupalSettings.bibcite_footnotes.references),
label: Drupal.t('Reference Footnote item:'),
setup: function (element) {
if (isEdit)
@ -65,6 +65,22 @@
this.fakeObj = CKEDITOR.plugins.reference_footnotes.getSelectedFootnote( editor );
this.realObj = editor.restoreRealElement( this.fakeObj );
}
var select = this.parts.contents.$.getElementsByTagName('select');
var selectBox = select.item(0);
// Remove all but the default 'None' item from teh list.
var i;
for (i = selectBox.options.length - 1 ; i >= 1 ; i--) {
selectBox.remove(i)
}
// Re-add buttons from the current state of Settings.
drupalSettings.bibcite_footnotes.references.forEach(function(reference) {
var newReference = document.createElement('option');
newReference.text = reference[0];
newReference.setAttribute("value", reference[1]);
selectBox.add(newReference);
});
this.setupContent( this.realObj );
},
onOk : function() {

28
js/replace_citations.js

@ -0,0 +1,28 @@
/**
* @file
* Provides JavaScript additions to entity embed dialog.
*
* This file provides popup windows for previewing embedded entities from the
* embed dialog.
*/
(function ($, Drupal) {
"use strict";
Drupal.behaviors.bibciteFootnotesReplaceCitations = {
attach: function attach(context, settings) {
/*
if (CKEDITOR.instances) {
for (var instance in CKEDITOR.instances) {
var editor = CKEDITOR.instances[instance];
var config = editor.config;
var name = editor.name;
editor.destroy();
CKEDITOR.replace(name, config);
}
}
*/
}
}
})(jQuery, Drupal);

23
src/Plugin/CKEditorPlugin/ReferenceFootnotes.php

@ -72,27 +72,6 @@ class ReferenceFootnotes extends CKEditorPluginBase {
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
$uid = \Drupal::currentUser()->id();
$query = \Drupal::service('entity.query');
$ref_ids = $query
->get('bibcite_reference')
->condition('uid', $uid)
->execute();
$reference_storage = \Drupal::entityTypeManager()->getStorage('bibcite_reference')->loadMultiple($ref_ids);
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('bibcite_reference');
$options = [];
foreach($reference_storage as $ref_id => $ref_item) {
$build = $view_builder->view($ref_item, 'citation');
$render = render($build);
$output = trim(strip_tags($render));
//$options[] = [$output, $ref_id];
$options[] = [$output, $ref_id];
}
return ['referenceFootnotes_list' => $options];
return [];
}
}

10
src/Plugin/Filter/ReferenceFootnotesFilter.php

@ -184,6 +184,8 @@ class ReferenceFootnotesFilter extends FootnotesFilter {
$randstr = $this->randstr();
$value = $this->extractAttribute($matches, 'value');
$page = $this->extractAttribute($matches, 'page');
$reference = $this->extractAttribute($matches, 'reference');
if ($value) {
// A value label was found. If it is numeric, record it in $n so further
@ -195,7 +197,7 @@ class ReferenceFootnotesFilter extends FootnotesFilter {
$n = $value;
}
}
elseif ($opt_collapse and $value_existing = $this->findFootnote($matches[2], $store_matches)) {
elseif ($opt_collapse and $value_existing = $this->findFootnote($matches[2], $reference, $store_matches)) {
// An identical footnote already exists. Set value to the previously
// existing value.
$value = $value_existing;
@ -211,8 +213,6 @@ class ReferenceFootnotesFilter extends FootnotesFilter {
// attribute.
$value_id = preg_replace('|[^\w\-]|', '', $value);
$page = $this->extractAttribute($matches, 'page');
$reference = $this->extractAttribute($matches, 'reference');
// Create a sanitized version of $text that is suitable for using as HTML
// attribute value. (In particular, as the title attribute to the footnote
@ -279,10 +279,10 @@ class ReferenceFootnotesFilter extends FootnotesFilter {
/**
* @inheritdoc
*/
private function findFootnote($text, &$store_matches) {
private function findFootnote($text, $reference, &$store_matches) {
if (!empty($store_matches)) {
foreach ($store_matches as &$fn) {
if ($fn['text'] == $text) {
if ($fn['text'] == $text && $fn['reference'] == $reference) {
return $fn['value'];
}
}

Loading…
Cancel
Save