-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TRY: Footnotes #2818
TRY: Footnotes #2818
Conversation
This is very much a work in progress. I just wanted some feedback on the approach. Currently footnotes are stored as attributes on the Footnotes block which is read-only. The biggest hurdle will be how to re-number footnotes when a new footnote is added (or one removed). Do we want to be iterating each node in every block (after the inserted foonote) to update the superscript footnote link? This can probably be made simpler by storing a mapping between footnoteId and blockId, to say where a footnote has been used... |
Hey @jasmussen @karmatosed can I pls get some feedback on this? If you're happy with the direction i'll keep going on Tuesday (public holiday on Monday in Australia!! |
Nice work! Looks like generally the right direction. A few quick questions, though:
Curious what @aduth thinks also. |
@jasmussen I was thinking the opposite might be better in regards to inserting the Footnotes block, you add the Footnotes block and this will add the Footnotes formatting option to the block toolbar? (this block will need to be single use and not moveable). The content is currently shown in the block in the editor but you need to blur the Paragraph Block, as currently content is only synced to redux state on focusout (there's another PR for this!) |
This is a good point, the contents of the footnotes need to be rich text. I do think the experience would be best if the block that holds the footnotes were inserted or appeared automatically (and also disappeared automatically if you removed all footnotes). Anything else is likely to be undiscoverable. |
@jasmussen sounds good I will make this change. The footnote content is currently just text (textarea)... |
Impressive, wasn't sure if the auto insertion/removal would be easy or hard. But it does seem like the best experience, that the two are connected directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the mechanisms for extensibility are not yet well-developed, but with these changes, we are hard-coding awareness of footnotes into:
- Block registration
- Formatting toolbar
- Editable
- Editor block rendering
This is not very maintainable, and honestly I'd prefer we go the route of introducing proper extensibility before considering this if this is what's necessary to implement footnotes.
@@ -56,6 +58,10 @@ class FormatToolbar extends Component { | |||
this.onChangeLinkValue = this.onChangeLinkValue.bind( this ); | |||
this.toggleLinkSettingsVisibility = this.toggleLinkSettingsVisibility.bind( this ); | |||
this.setLinkTarget = this.setLinkTarget.bind( this ); | |||
|
|||
this.addFootnote = this.addFootnote.bind( this ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: #2474
This is begging to be extensible behavior, not engrained into the toolbar itself.
blocks/editable/index.js
Outdated
} else if ( format === 'footnote' ) { | ||
const footnoteId = uuid(); | ||
this.footnotes[ footnoteId ] = formatValue.text; | ||
this.editor.selection.setContent( `<a href="#footnote-${ footnoteId }" data-footnote-id="${ footnoteId }" contenteditable="false"><sup>[*]</sup></a>` ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is being persisted into the saved content of the post, which is problematic because we don't want/care for this editor-specific attribute to be present on the front-end of the site. Also, it's causing React to log a warning into the developer console.
registerBlockType( 'core/footnotes', { | ||
title: __( 'Footnotes' ), | ||
|
||
icon: 'button', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guessing this block could use the once: true
flag (see also: "More" block)
@@ -0,0 +1,35 @@ | |||
import { mapKeys } from 'lodash'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/**
* External dependencies
*/
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
import { registerBlockType } from '../../api'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/**
* Internal dependencies
*/
blocks/library/paragraph/index.js
Outdated
setAttributes( { | ||
content: nextContent, | ||
content: nextContent.content, | ||
footnotes: nextContent.footnotes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is causing paragraph blocks to include an empty footnotes
object in comment serialized block attributes whenever the text is changed (regardless of adding footnotes). We should avoid this being included for paragraphs which aren't using footnotes.
@aduth this is still very much a work in progress... Would like some feedback on the API to add formatters to Editable... gutenberg/blocks/library/paragraph/index.js Line 109 in ece64ee
|
@jasmussen : can we just check - with the proposal to auto insert/remove the footnote block, this assumes that the "Insert Footnote" button is always visible in the toolbar. Is this OK? |
@annaephox
Yes, that's fine. We are separaretly ( #2898 ) tracking how to improve many buttons in the quick toolbar, and worst case scenario we can look at moving the button to the inspector sidebar and call it an "advanced feature". This shouldn't block us for now! 👍 👍 |
|
||
this.footnotes = this.props.attributes.footnotes || {}; | ||
|
||
this.footnoteFormatter = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to require a significant amount of effort on the part of the block implementer to track the state of the active node in TinyMCE and apply formatting.
If I understand correctly the needs around identifying and applying formats / tokens, there's a few things which would be ideal:
- A reasonable API in TinyMCE to define formats / token types, how they’re identified & applied, maybe emitting specific events when the selection becomes "active" for this type (to integrate with toolbar)
- Define a set of built-in / global formats: bold, italic, strikethrough, footnotes
- Managed within Editable, not surfaced to block implementer
- If possible, expose a simple-to-use prop on Editable for custom formats
So extending the bold, italic idea, one could enable a footnotes format on Editable via formattingControls={ [ 'bold', 'footnotes' ] }
.
It seems like there could be some overlap here with how TinyMCE enables toolbar buttons to be defined with a stateSelector
property that handles much of the work around determining whether a button should be active or not.
Closing in favor of the existing issue (#1890). We can pull what we need from this PR when that moves forward. |
Description
fixes #1890
Todo:
Footnote Entry
Footnotes Block
How Has This Been Tested?
Screenshots (jpeg or gifs if applicable):
Types of changes
Checklist: