Browse Source

Issue #3007407 by alxp: Add support for free-form text notes

config_filter 8.x-1.0-beta1
Alexander O'Neill 6 years ago
parent
commit
c094983d60
  1. 0
      LICENSE
  2. 8
      README.md
  3. 8
      bibcite_footnotes.info.yml
  4. 5
      bibcite_footnotes.libraries.yml
  5. 110
      bibcite_footnotes.module
  6. 8
      css/reference_footnote.css
  7. BIN
      js/plugins/reference_footnotes/.DS_Store
  8. 20
      js/plugins/reference_footnotes/dialogs/footnotes.js
  9. BIN
      js/plugins/reference_footnotes/images/fn_icon2.png
  10. BIN
      js/plugins/reference_footnotes/images/fn_icon3.png
  11. 36
      js/plugins/reference_footnotes/plugin.js
  12. 21
      templates/footnote-list.html.twig

0
LICENSE.txt → LICENSE

8
README.md

@ -23,7 +23,13 @@ Installation
------------ ------------
Install and set up the Footnotes module as per its installation instructions, including Install and set up the Footnotes module as per its installation instructions, including
enabling and configuring the Footnotes text filter. enabling and configuring the Footnotes text filter. If the 'Allowed HTML tags' filter is enabled
you will need to add the following HTML tags for the reference footnotes to display properly.:
```html
<a class href id> <div class id> <span class id> <ul class id type>
<ol class id start type> <sup> <li class id>
```
Configuration Configuration
------------- -------------

8
bibcite_footnotes.info.yml

@ -1,9 +1,15 @@
name: 'BibCite Footnotes' name: 'BibCite Footnotes'
type: module type: module
description: 'Inline footnote links for BibCite References' description: 'Inline footnote links for BibCite References'
core: 8.x # core: 8.x
package: 'Bibliography & Citation' package: 'Bibliography & Citation'
dependencies: dependencies:
- bibcite:bibcite - bibcite:bibcite
- bibcite:bibcite_entity - bibcite:bibcite_entity
- footnotes:footnotes - footnotes:footnotes
# Information added by Drupal.org packaging script on 2018-07-30
version: '8.x-1.0-alpha5'
core: '8.x'
project: 'bibcite_footnotes'
datestamp: 1532941092

5
bibcite_footnotes.libraries.yml

@ -0,0 +1,5 @@
reference_footnote:
version: VERSION
css:
theme:
css/reference_footnote.css: {}

110
bibcite_footnotes.module

@ -6,6 +6,8 @@
*/ */
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Core\Link;
/** /**
* Implements hook_help(). * Implements hook_help().
@ -23,6 +25,96 @@ function bibcite_footnotes_help($route_name, RouteMatchInterface $route_match) {
} }
} }
function bibcite_footnotes_preprocess_footnote_list(&$variables) {
// Drupal 7 requires we use "render element" which just introduces a wrapper
// around the old array.
// $footnotes = $footnotes['footnotes'];
// loop through the footnotes.
$footnotes = $variables['footnotes'];
$notes = [
'#theme' => 'item_list',
'#list_type' => 'ul',
'#title' => 'Notes',
'#attributes' => ['class' => 'footnotes'],
'#wrapper_attributes' => ['class' => 'container'],
];
$references= [
'#theme' => 'item_list',
'#list_type' => 'ul',
'#title' => 'References',
'#attributes' => ['class' => 'footnotes'],
'#wrapper_attributes' => ['class' => 'container'],
];
$references['#attached']['library'][] = 'bibcite_footnotes/reference_footnote';
$serializer = \Drupal::service('serializer');
foreach ($footnotes as $fn) {
$item = [
'#id' => $fn['fn_id'],
'#wrapper_attributes' => [
'class' => ['footnote'],
],
];
$build = [];
if (!is_array($fn['ref_id'])) {
// Output normal footnote.
$url = Url::fromUserInput('#' . $fn['ref_id'], ['attributes' => ['id' => $fn['fn_id'], 'class' => 'footnote-link']]);
$link = Link::fromTextAndUrl($fn['value'], $url)->toRenderable();
$build[] = $link;
}
else {
// Output footnote that has more than one reference to it in the body.
// The only difference is to insert backlinks to all references.
// Helper: we need to enumerate a, b, c...
$abc = str_split("abcdefghijklmnopqrstuvwxyz");
$i = 0;
$url = Url::fromUserInput('#' . $fn['ref_id'][0], ['attributes' => ['id' => $fn['fn_id'], 'class' => 'footnote-link']]);
$build[] = Link::fromTextAndUrl($fn['value'], $url)->toRenderable();
foreach ($fn['ref_id'] as $ref) {
$url = Url::fromUserInput( '#' . $ref, ['attributes' => ['id' => $fn['fn_id'], 'class' => 'footnote-multi']]);
$build[] = Link::fromTextAndUrl($abc[$i], $url)->toRenderable();
$i++;
}
}
preg_match('/\[bibcite_reference:(\d*)\]/', $fn['text'], $matches);
$reference_entity_id = $matches[1];
if (!empty($reference_entity_id)) {
$reference_storage = \Drupal::entityTypeManager()
->getStorage('bibcite_reference')
->load($reference_entity_id);
$data = $serializer->normalize($reference_storage, 'csl');
$build[] = ['#theme' => 'bibcite_citation', '#data' => $data];
$render = render($build);
$item['#markup'] = $render;
$references['#items'][] = $item;
}
else {
$build[] = ['#type' => 'markup', '#markup' => ' ' . $fn['text']];
$render = render($build);
$item['#markup'] = $render;
$notes['#items'][] = $item;
}
}
$variables['notes'] = $notes;
$variables['references'] = $references;
}
/** /**
* Implements hook_theme(). * Implements hook_theme().
*/ */
@ -35,12 +127,28 @@ function bibcite_footnotes_theme() {
} }
function bibcite_footnotes_theme_registry_alter(&$theme_registry) { function bibcite_footnotes_theme_registry_alter(&$theme_registry) {
$theme_registry['footnote_list']['function'] = 'bibcite_footnotes_theme_footnote_list'; unset($theme_registry['footnote_list']['function']);
// $theme_registry['footnote_list']['function'] = 'bibcite_footnotes_theme_footnote_list';
$theme_registry['footnote_list']['path'] = drupal_get_path('module', 'bibcite_footnotes') . '/templates';
$theme_registry['footnote_list']['template'] = 'footnote-list';
$theme_registry['footnote_list']['variables']['notes'] = [];
$theme_registry['footnote_list']['variables']['references'] = [];
$theme_registry['footnote_list']['variables']['footnotes'] = [];
} }
function bibcite_footnotes_theme_footnote_list($footnotes) { function bibcite_footnotes_theme_footnote_list($footnotes) {
// @todo: change this ugly array for arguments in the function. // @todo: change this ugly array for arguments in the function.
$footnotes = $footnotes['footnotes']['#footnotes']; $footnotes = $footnotes['footnotes']['#footnotes'];
$notes = [
'#theme' => 'item_list',
'#list_type' => 'ul',
'#title' => 'Notes',
'#attributes' => ['class' => ''],
'#wrapper_attributes' => ['class' => 'container'],
];
// return drupal_render($content);
$str = '<ul class="footnotes">'; $str = '<ul class="footnotes">';
// Drupal 7 requires we use "render element" which just introduces a wrapper // Drupal 7 requires we use "render element" which just introduces a wrapper
// around the old array. // around the old array.

8
css/reference_footnote.css

@ -0,0 +1,8 @@
.footnotes .footnote .footnote-link {
float: left;
}
.footnotes .footnote .footnote-link::after {
content: " ";
white-space: pre;
}

BIN
js/plugins/reference_footnotes/.DS_Store vendored

Binary file not shown.

20
js/plugins/reference_footnotes/dialogs/footnotes.js

@ -20,13 +20,22 @@
if (isEdit) if (isEdit)
this.setValue(element.getText()); this.setValue(element.getText());
} }
},
{
id: 'footnote',
type: 'text',
label: Drupal.t('Or add free-form footnote text :'),
setup: function (element) {
if (isEdit)
this.setValue(element.getText());
}
}, },
{ {
id: 'value', id: 'value',
type: 'text', type: 'text',
label: Drupal.t('Value :'), label: Drupal.t('Value :'),
labelLayout: 'horizontal', labelLayout: 'horizontal',
style: 'float:left;width:100px;', style: 'float:left;width:200px;',
setup: function (element) { setup: function (element) {
if (isEdit) if (isEdit)
this.setValue(element.getAttribute('value')); this.setValue(element.getAttribute('value'));
@ -43,17 +52,20 @@
this.setupContent( this.realObj ); this.setupContent( this.realObj );
}, },
onOk : function() { onOk : function() {
CKEDITOR.plugins.reference_footnotes.createFootnote( editor, this.realObj, this.getValueOf('info', 'reference_footnote'), this.getValueOf('info', 'value')); var referenceNote = this.getValueOf('info', 'reference_footnote');
var textNote = this.getValueOf('info', 'footnote');
var value = textNote ? textNote : referenceNote;
CKEDITOR.plugins.reference_footnotes.createFootnote( editor, this.realObj, value, this.getValueOf('info', 'value'));
delete this.fakeObj; delete this.fakeObj;
delete this.realObj; delete this.realObj;
} }
} }
} }
CKEDITOR.dialog.add( 'createfootnotes', function( editor ) { CKEDITOR.dialog.add( 'createreferencefootnotes', function( editor ) {
return referenceFootnotesDialog( editor ); return referenceFootnotesDialog( editor );
}); });
CKEDITOR.dialog.add( 'editfootnotes', function( editor ) { CKEDITOR.dialog.add( 'editreferencefootnotes', function( editor ) {
return referenceFootnotesDialog( editor, 1 ); return referenceFootnotesDialog( editor, 1 );
}); });
})(); })();

BIN
js/plugins/reference_footnotes/images/fn_icon2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

BIN
js/plugins/reference_footnotes/images/fn_icon3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

36
js/plugins/reference_footnotes/plugin.js

@ -5,7 +5,16 @@
icons: 'reference_footnotes', icons: 'reference_footnotes',
onLoad: function() { onLoad: function() {
var icon_path = window.location.origin + this.path + 'images/fn_icon2.png'; var icon_path = window.location.origin + this.path + 'images/fn_icon2.png';
var ref_icon_path = window.location.origin + this.path + 'images/fn_icon3.png';
CKEDITOR.addCss( CKEDITOR.addCss(
'.cke_reference_footnote' +
'{' +
'background-image: url(' + CKEDITOR.getUrl( ref_icon_path ) + ');' +
'background-position: center center;' +
'background-repeat: no-repeat;' +
'width: 16px;' +
'height: 16px;' +
'}' +
'.cke_footnote' + '.cke_footnote' +
'{' + '{' +
'background-image: url(' + CKEDITOR.getUrl( icon_path ) + ');' + 'background-image: url(' + CKEDITOR.getUrl( icon_path ) + ');' +
@ -14,14 +23,15 @@
'width: 16px;' + 'width: 16px;' +
'height: 16px;' + 'height: 16px;' +
'}' '}'
); );
}, },
init: function( editor ) init: function( editor )
{ {
editor.addCommand('createfootnotes', new CKEDITOR.dialogCommand('createfootnotes', { editor.addCommand('createreferencefootnotes', new CKEDITOR.dialogCommand('createreferencefootnotes', {
allowedContent: 'fn[value]' allowedContent: 'fn[value]'
})); }));
editor.addCommand('editfootnotes', new CKEDITOR.dialogCommand('editfootnotes', { editor.addCommand('editreferencefootnotes', new CKEDITOR.dialogCommand('editreferencefootnotes', {
allowedContent: 'fn[value]' allowedContent: 'fn[value]'
})); }));
@ -30,7 +40,7 @@
// in hook_wysiwyg_plugin(). // in hook_wysiwyg_plugin().
editor.ui.addButton && editor.ui.addButton( 'reference_footnotes', { editor.ui.addButton && editor.ui.addButton( 'reference_footnotes', {
label: Drupal.t('Add a reference footnote'), label: Drupal.t('Add a reference footnote'),
command: 'createfootnotes', command: 'createreferencefootnotes',
icon: 'reference_footnotes' icon: 'reference_footnotes'
}); });
@ -39,7 +49,7 @@
editor.addMenuItems({ editor.addMenuItems({
footnotes: { footnotes: {
label: Drupal.t('Edit footnote'), label: Drupal.t('Edit footnote'),
command: 'editfootnotes', command: 'editreferencefootnotes',
icon: 'reference_footnotes', icon: 'reference_footnotes',
group: 'reference_footnotes' group: 'reference_footnotes'
} }
@ -55,12 +65,14 @@
} }
editor.on( 'doubleclick', function( evt ) { editor.on( 'doubleclick', function( evt ) {
if ( CKEDITOR.plugins.footnotes.getSelectedFootnote( editor ) ) if ( CKEDITOR.plugins.reference_footnotes.getSelectedFootnote( editor ) )
evt.data.dialog = 'editfootnotes'; {
}); evt.data.dialog = 'editreferencefootnotes';
}
}, null, null, 1); // Ensure this event fires after the 'footnotes' event so we can decide which dialog to show.
CKEDITOR.dialog.add( 'createfootnotes', this.path + 'dialogs/footnotes.js' ); CKEDITOR.dialog.add( 'createreferencefootnotes', this.path + 'dialogs/footnotes.js' );
CKEDITOR.dialog.add( 'editfootnotes', this.path + 'dialogs/footnotes.js' ); CKEDITOR.dialog.add( 'editreferencefootnotes', this.path + 'dialogs/footnotes.js' );
}, },
afterInit : function( editor ) { afterInit : function( editor ) {
var dataProcessor = editor.dataProcessor, var dataProcessor = editor.dataProcessor,
@ -70,7 +82,9 @@
dataFilter.addRules({ dataFilter.addRules({
elements: { elements: {
fn: function(element ) { fn: function(element ) {
return editor.createFakeParserElement( element, 'cke_footnote', 'hiddenfield', false );
return editor.createFakeParserElement(element, 'cke_reference_footnote', 'hiddenfield', false);
} }
} }
}); });
@ -93,7 +107,7 @@ CKEDITOR.plugins.reference_footnotes = {
if (value && value.length > 0 ) if (value && value.length > 0 )
realElement.setAttribute('value',value); realElement.setAttribute('value',value);
var fakeElement = editor.createFakeElement( realElement , 'cke_footnote', 'hiddenfield', false ); var fakeElement = editor.createFakeElement( realElement , 'cke_reference_footnote', 'hiddenfield', false );
editor.insertElement(fakeElement); editor.insertElement(fakeElement);
}, },

21
templates/footnote-list.html.twig

@ -0,0 +1,21 @@
{#
/**
* @file footnote-list.html.twig
* Default theme implementation to present a list of reference footnotes.
*
* Available variables:
* - footnotess: A list of footnotes
* - notes: A list of free-form notes
* - references: A list of citations
* - attributes: HTML attributes for the container element.
*
* @see template_preprocess_footnote_list().
*
* @ingroup themeable
*/
#}
<div{{ attributes.addClass('footnote-list') }}>
{{ notes }}
{{ references }}
</div>
Loading…
Cancel
Save