carlcs / craft-footnote

Footnote plugin for Craft CMS
MIT License
14 stars 4 forks source link

Craft 3 - Fails to Initialize? #4

Closed michaelpelletier closed 5 years ago

michaelpelletier commented 5 years ago

Hey! Getting an error trying to set this up for Craft 3.

jquery.js:3869 Uncaught TypeError: Cannot read property 'icon' of undefined
    at start (footnotes.js?v=1556553051:1)
    at App.callInstanceMethod (redactor.js:2361)
    at s._startStop (redactor.js:10025)
    at s.onenable (redactor.js:10007)
    at App.callMessageHandler (redactor.js:2249)
    at App.broadcast (redactor.js:2268)
    at App.start (redactor.js:2119)
    at new App (redactor.js:2102)
    at RedactorApp (redactor.js:1396)
    at k.fn.init.jQuery.fn.redactor (redactor.js:1375)

Which comes out to it having a problem with Craft.Footnotes in the footnotes.js:

            var t = {
                title: Craft.t("footnotes", "Footnote"),
                icon: Craft.Footnotes.icon,
                api: "module.inline.format",
                args: {
                    tag: "span",
                    class: "fn-marker",
                    type: "toggle"
                }
            };

Near as I can tell, it installed correctly, but a few things in the instructions reference the old Craft 2 directory so I'm wondering if there's something more I need to do that isn't documented yet.

Any help would be very appreciated!

carlcs commented 5 years ago

First of all, sorry for the poor docs for the Craft 3 version. I just added a link to a document to the readme that should help you get started: https://gist.github.com/carlcs/a8c51bb7bbeb3350e549a6ba3cd27f7a

About the error you’re seeing, can you please open your browser’s dev tools and enter Craft.Footnotes into the JS console, then send me the value it outputs?

michaelpelletier commented 5 years ago

No worries on the lack of docs, and I appreciate the reply! I know the plugin is in Beta and was trying to forge ahead regardless, haha.

Perhaps as expected, Craft.Footnotes returns undefined. I didn't see any errors during the install of the plugin itself, but it strangely doesn't appear to have synced with Craft.

carlcs commented 5 years ago

I just updated the plugin scripts load order in the develop branch, can you please install that on your environment and report back if that fixes things for you.

composer require carlcs/craft-footnotes:dev-develop

If the issue still occurs, please search the HTML of a CP page that loads Redactor for a script tag that contains Craft.Footnotes.

michaelpelletier commented 5 years ago

Yup, same problem, unfortunately. :-/

This is the only instance of Craft.Footnotes that I'm seeing in the DOM structure.

Screen Shot 2019-05-01 at 8 24 06 AM
carlcs commented 5 years ago

That’s weird, can you please double check if there is in fact no Craft.Footnotes variable definition in the script tag two lines above the one you’re looking at.

michaelpelletier commented 5 years ago

Huh, this is interesting.

Okay so here's what I'm seeing: footnotes.js and footnotes.css are loaded in from the same cpresources subfolder and load just fine. That footnotes.js file contains

!function(t){var o={};function n(e){if(o[e])return o[e].exports;var r=o[e]={i:e,l:!1,exports:{}};return t[e].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=o,n.d=function(t,o,e){n.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(o,"a",o),o},n.o=function(t,o){return Object.prototype.hasOwnProperty.call(t,o)},n.p="/",n(n.s=0)}([function(t,o,n){n(1),t.exports=n(2)},function(t,o){Redactor.add("plugin","footnotes",{init:function(t){this.app=t,this.lang=t.lang,this.opts=t.opts,this.toolbar=t.toolbar,this.addAfter=this.opts.footnoteAddAfter||this.opts.footnoteaddafter||"lists"},start:function(){var t={title:Craft.t("footnotes","Footnote"),icon:Craft.Footnotes.icon,api:"module.inline.format",args:{tag:"span",class:"fn-marker",type:"toggle"}};this.toolbar.addButtonAfter(this.addAfter,"footnote",t)}})},function(t,o){}]);

Which I would admittedly have expected to work.

There is also a second footnotes.js file included, in a different cpresources subfolder, bu that file seems to just be an empty js file. Maybe something isn't being copied over correctly?

Otherwise, yeah, I'm still getting Craft.Footnotes as undefined, and I'm not seeing any errors in installation that might explain what's happening.

carlcs commented 5 years ago

I meant the script tag with the inline code. Everything else you describe is expected, the empty script is needed to register the plugin with the Redactor plugin.

carlcs commented 5 years ago

Have you tried a different browser or incognito window?

michaelpelletier commented 5 years ago

Yeah, tried both Safari and Incognito Chrome, same issue. :-/

carlcs commented 5 years ago

Can you send me your composer.json, composer.lock, and config/redactor/ files over to carlcs@icloud.com

michaelpelletier commented 5 years ago

Looking into it further, I've found that it works in some places in not others (like it works if I create a new Entry, but not if I edit an Entry that already existed before installing the plugin). Also if I create an entry and then go to Live Preview it, it breaks there, too. This is so strange.

carlcs commented 5 years ago

I was now able to reproduce the issue when using the plugin with a Redactor field that is used within a Matrix block. To get the fix, update to the latest beta.

composer require carlcs/craft-footnotes:^2.0.0-beta.3
michaelpelletier commented 5 years ago

Sweet, that does seem to fix that!

Hopefully this is the last thing to get this 100%:

Adding a new Footnote to the Redactor field seems to work correctly (see 2 in the screenshot below), but when I go back to edit an existing Entry, it's relegated to just being a simple redactor span (see 1 in the screenshot below)

Screen Shot 2019-05-06 at 8 42 42 AM

I don't know if this is intentional or not, but in either case it seems to not be "mapping" correctly when I view the entry on the site - the inline footnote is parsing as just a span, and while {% do parseFootnoteDefinitions(block.footnotes) %} does seem to return the footnotes themselves, {{ getFootnotesHtml() }} is also not returning anything.

carlcs commented 5 years ago

Phew, I can again not reproduce the issue in the Redactor field you are seeing. The markers need to save as <span class="fn-marker">some-id</span> to get parsed by the parseFootnoteDefinitions() function correctly.

carlcs commented 5 years ago

You can try to disable all cleansing in the field settings, and disable HTML Purifyier.

michaelpelletier commented 5 years ago

Disabling cleansing fixes the problem with fn-marker not rendering in Redactor. I still have the DOM not rendering things, though. It's acting now like parseFootnoteMarkers is stripping out markers and not actually linking them to anything.

Screen Shot 2019-05-06 at 11 26 26 AM

I've tried making the footnotes both a separate block and a subset of the text block and neither approach seems to work.

Screen Shot 2019-05-06 at 11 26 45 AM Screen Shot 2019-05-06 at 11 26 41 AM
carlcs commented 5 years ago

I’m glad to hear you have the Redactor part working, finally.

The parseFootnoteDefinitions() function by default expects footnotes definitions passed as paragraphs from a Redactor field, so you can have links within the footnote. It’s using a regular expression that parses for <p>1. My footnote definition</p>.

It looks like you’re using a Plain Text field, which you can use as well, but you need to configure the plugin via a config/footnotes.php file.

return [
    'definitionSyntax' = 'plaintext';
];

You can see the available parsing presets (and regular expression) here: https://github.com/carlcs/craft-footnotes/blob/b37fbaf4534181baa55c5651dbddf358c7b89c8d/src/models/Settings.php#L25-L34

carlcs commented 5 years ago

It just occurred to me, that you can also set the parsing preset in the Twig function directly. https://github.com/carlcs/craft-footnotes/blob/v2/src/Footnotes.php#L53

{% do parseFootnoteDefinitions(block.footnotes, definitionSyntax='plaintext') %}
michaelpelletier commented 5 years ago

Bleh. I have the same thing happen when using Redactor fields for the Footnotes, or when changing the definition syntax. I'll keep trying to fiddle with it.

carlcs commented 5 years ago

Make sure you loop twice through your Matrix blocks, so footnote definitions are parsed and memorized before you are parsing for markers. There is a removeUnmatchedMarkers config setting that might help debugging https://github.com/carlcs/craft-footnotes/blob/b37fbaf4534181baa55c5651dbddf358c7b89c8d/src/models/Settings.php#L70.

carlcs commented 5 years ago

https://gist.github.com/carlcs/a8c51bb7bbeb3350e549a6ba3cd27f7a#usage-with-a-matrix-field

michaelpelletier commented 5 years ago

Ah! The double looping was the problem, I was trying to evaluate it within my normal block loop. I do believe this all works as expected now. Thanks so very much for all the help with debugging!

carlcs commented 5 years ago

You are welcome, Michael. Good luck with the templating part now, in case you didn’t notice, there is a folder with example templates in the repo https://github.com/carlcs/craft-footnotes/tree/v2/_examples

Usage: https://gist.github.com/carlcs/a8c51bb7bbeb3350e549a6ba3cd27f7a#custom-templates

michaelpelletier commented 5 years ago

Hey one more thing I noticed!

I'm looking to use the Redactor input for the Footnotes itself because I want to be able to add links, and it automatically converts 1. Text into an OL with an LI, which the plugin doesn't parse because it's looking for P tags. Mostly just checking to see if that's a known thing / has an established workaround.

carlcs commented 5 years ago

Good question. You can provide your own regular expression via the plugin config file, and parse for <li> tags. Not sure how you’d get the number for the footnote ID though. Another idea would be to instruct the content editor to not use numbers for IDs, so Redactor doesn’t auto-convert. What you can also do is to use a Super Table, configured with one field for the index and one for the text. A dedicated entry channel for footnotes works too, if that makes sense for your type of footnotes.

michaelpelletier commented 5 years ago

Wait, why would it alter how you get the numbers for the ID footnote?

I'm proposing this change:

<p>1. First Footnote.</p>
<p>2. Second footnote.</p>
<ol>
<li>1. First Footnote.</li>
<li>2. Second footnote.</li>
</ol>

When you start typing 1. A into a redactor field, it automatically converts it to being an OL/LI, so it make sense to me to just leverage that instead of relying the user to manually change the tags. Using something that isn't a number is a good alternative, but numbers are the most common use for footnotes.

But I'll try adding in a custom regular expression and see how that goes!

carlcs commented 5 years ago

Text you use for the ID in the marker and in the footnote is not what is eventually output in the frontend, it’s just used to match markers to notes. So you can do, for example, <p>first-note. First Footnote.</p> and <p>lorem ipsum<span class="fn-marker>first-note</span></p> and the footnotes list in the frontend outputs the marker and list with numbers. This is so that you can later insert marker in between existing ones and don‘t have to care about updating all IDs.

About the issue with Redactor auto-converting 1. to lists, I think that’s a new behavior and wasn‘t like that in previous versions. And I agree it‘s not very user friendly to always un-list the block.

I currently have just one project where we are using the Craft 3 version of the plugin, and have footnotes setup as a channel. for markers we don’t use its Redactor plugin at all, to be able to add footnotes to plain text fields we decided to enter markers in [^myFootnoteId] markdown syntax.

Here’s a screenshot of a footnotes entry

Bildschirmfoto 2019-05-09 um 16 19 02