Skip to content
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

Add Gutenberg support to the plugin #34

Merged
merged 49 commits into from
Aug 31, 2018
Merged

Add Gutenberg support to the plugin #34

merged 49 commits into from
Aug 31, 2018

Conversation

benlk
Copy link
Collaborator

@benlk benlk commented Aug 27, 2018

Changes

  • registers a Gutenberg block

To do list

@benlk
Copy link
Collaborator Author

benlk commented Aug 28, 2018

With the following post_content:

<!-- wp:shortcode -->
[pym src="https://f.benlk.com/graphics/heartbeat-abortion-bills/child.html"]
<!-- /wp:shortcode -->

<!-- wp:paragraph -->
<p>the preceding is a shortcode block.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The following is the Pym Embed:</p>
<!-- /wp:paragraph -->

<!-- wp:pym-shortcode/pym {"src":"http://blog.apps.npr.org/pym.js/examples/table/child.html","align":"full"} /-->

The following output:

<div id="pym_1" class="pym  "></div>
<script>var pym_1 = new pym.Parent('pym_1', 'https://f.benlk.com/graphics/heartbeat-abortion-bills/child.html', {})</script>

<p>the preceding is a shortcode block.</p>
<p>The following is the Pym Embed:</p>
<div id="pym_0" class="pym alignfull "></div>
<script src="http://pym-shortcode.test/wp-content/plugins/pym-shortcode/js/pym.v1.min.js"></script><script>var pym_0 = new pym.Parent('pym_0', 'http://blog.apps.npr.org/pym.js/examples/table/child.html', {})</script>

Why does the first one have a later ID? Does the block renderer run before the shortcode renderer? How can it be assured that the script source is output before any and all tags?

@benlk
Copy link
Collaborator Author

benlk commented Aug 29, 2018

Long long debug output
wp> global $wp_filter; var_dump( $wp_filter['the_content'], true );
object(WP_Hook)#1139 (5) {
  ["callbacks"]=>
  array(5) {
    [8]=>
    array(3) {
      ["00000000430b60a000000000382d9011run_shortcode"]=>
      array(2) {
        ["function"]=>
        array(2) {
          [0]=>
          object(WP_Embed)#1440 (7) {
            ["handlers"]=>
            array(2) {
              [10]=>
              array(1) {
                ["youtube_embed_url"]=>
                array(2) {
                  ["regex"]=>
                  string(51) "#https?://(www.)?youtube\.com/(?:v|embed)/([^/]+)#i"
                  ["callback"]=>
                  string(24) "wp_embed_handler_youtube"
                }
              }
              [9999]=>
              array(2) {
                ["audio"]=>
                array(2) {
                  ["regex"]=>
                  string(41) "#^https?://.+?\.(mp3|ogg|flac|m4a|wav)$#i"
                  ["callback"]=>
                  string(22) "wp_embed_handler_audio"
                }
                ["video"]=>
                array(2) {
                  ["regex"]=>
                  string(41) "#^https?://.+?\.(mp4|m4v|webm|ogv|flv)$#i"
                  ["callback"]=>
                  string(22) "wp_embed_handler_video"
                }
              }
            }
            ["post_ID"]=>
            NULL
            ["usecache"]=>
            bool(true)
            ["linkifunknown"]=>
            bool(true)
            ["last_attr"]=>
            array(0) {
            }
            ["last_url"]=>
            string(0) ""
            ["return_false_on_fail"]=>
            bool(false)
          }
          [1]=>
          string(13) "run_shortcode"
        }
        ["accepted_args"]=>
        int(1)
      }
      ["00000000430b60a000000000382d9011autoembed"]=>
      array(2) {
        ["function"]=>
        array(2) {
          [0]=>
          object(WP_Embed)#1440 (7) {
            ["handlers"]=>
            array(2) {
              [10]=>
              array(1) {
                ["youtube_embed_url"]=>
                array(2) {
                  ["regex"]=>
                  string(51) "#https?://(www.)?youtube\.com/(?:v|embed)/([^/]+)#i"
                  ["callback"]=>
                  string(24) "wp_embed_handler_youtube"
                }
              }
              [9999]=>
              array(2) {
                ["audio"]=>
                array(2) {
                  ["regex"]=>
                  string(41) "#^https?://.+?\.(mp3|ogg|flac|m4a|wav)$#i"
                  ["callback"]=>
                  string(22) "wp_embed_handler_audio"
                }
                ["video"]=>
                array(2) {
                  ["regex"]=>
                  string(41) "#^https?://.+?\.(mp4|m4v|webm|ogv|flv)$#i"
                  ["callback"]=>
                  string(22) "wp_embed_handler_video"
                }
              }
            }
            ["post_ID"]=>
            NULL
            ["usecache"]=>
            bool(true)
            ["linkifunknown"]=>
            bool(true)
            ["last_attr"]=>
            array(0) {
            }
            ["last_url"]=>
            string(0) ""
            ["return_false_on_fail"]=>
            bool(false)
          }
          [1]=>
          string(9) "autoembed"
        }
        ["accepted_args"]=>
        int(1)
      }
      ["gutenberg_wpautop"]=>
      array(2) {
        ["function"]=>
        string(17) "gutenberg_wpautop"
        ["accepted_args"]=>
        int(1)
      }
    }
    [9]=>
    array(1) {
      ["do_blocks"]=>
      array(2) {
        ["function"]=>
        string(9) "do_blocks"
        ["accepted_args"]=>
        int(1)
      }
    }
    [10]=>
    array(4) {
      ["wptexturize"]=>
      array(2) {
        ["function"]=>
        string(11) "wptexturize"
        ["accepted_args"]=>
        int(1)
      }
      ["shortcode_unautop"]=>
      array(2) {
        ["function"]=>
        string(17) "shortcode_unautop"
        ["accepted_args"]=>
        int(1)
      }
      ["prepend_attachment"]=>
      array(2) {
        ["function"]=>
        string(18) "prepend_attachment"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_make_content_images_responsive"]=>
      array(2) {
        ["function"]=>
        string(33) "wp_make_content_images_responsive"
        ["accepted_args"]=>
        int(1)
      }
    }
    [11]=>
    array(2) {
      ["capital_P_dangit"]=>
      array(2) {
        ["function"]=>
        string(16) "capital_P_dangit"
        ["accepted_args"]=>
        int(1)
      }
      ["do_shortcode"]=>
      array(2) {
        ["function"]=>
        string(12) "do_shortcode"
        ["accepted_args"]=>
        int(1)
      }
    }
    [20]=>
    array(1) {
      ["convert_smilies"]=>
      array(2) {
        ["function"]=>
        string(15) "convert_smilies"
        ["accepted_args"]=>
        int(1)
      }
    }
  }
  ["iterations":"WP_Hook":private]=>
  array(0) {
  }
  ["current_priority":"WP_Hook":private]=>
  array(0) {
  }
  ["nesting_level":"WP_Hook":private]=>
  int(0)
  ["doing_action":"WP_Hook":private]=>
  bool(false)
}
Looks like yes, the block renderer does run before the shortcode renderer.

@benlk
Copy link
Collaborator Author

benlk commented Aug 29, 2018

Hrm, how might this work:

  1. Add a filter to the_content that checks for the presence of the string 'pym', and if it is there, sets a global "maybe" variable to true
  2. In the pym renderer, if it is called, if the tag doesn't have its own pymsrc, set a global definitely variable to true. If pymsrc is set, then instead output the pymsrc's tag
  3. In a filter running on the_content that runs at a very late priority, like 100, if $maybe and $definitely, prepend the_content with a script tag that registers Pym.

Alternately:

  1. Everytime we would output a <script>var pym_1 = new pym.Parent('pym_1', 'https://f.benlk.com/graphics/heartbeat-abortion-bills/child.html', {})</script> , instead of outputting it then, add it to the footer with a generated callback function that has the correct variables inserted into its call!

…footer action.

This addresses the problem described at #34 (comment)

WordPress renders blocks before rendering shortcodes. If a post contains a Pym shortcode followed by a Pym block, the shortcode, which appears first, will have the id pym_1 and the block, which is processed first, will have the id pym_0. Because the script tag that loads `pym.js`, `<script src="http://example.org/wp-content/plugins/pym-shortcode/js/pym.v1.min.js"></script>` is output on the first *processed* Pym thing, it's not output on the page until after pym_1's `new pym.Parent` was called. Because the `pym.js` library isn't loaded on the page until pym_0, at pym_1 `new pym.Parent` will fail.

This commit solves the problem by:
- not messing with block or shortcode rendering order
- not moving the `<script src="http://example.org/wp-content/plugins/pym-shortcode/js/pym.v1.min.js"></script>`
- moving the `new pym.Parent` calls to after the entire post_content has been processed, by outputting them in the `wp_footer` action

A problem I foresee with this approach is that the output of the_content() no longer contains all elements necessary to display the post.
@benlk
Copy link
Collaborator Author

benlk commented Aug 29, 2018

Gonna open a separate issue for this problem, because that makes it easier to discuss separately from "should we implement blocks".

@benlk benlk self-assigned this Aug 29, 2018
- Fixes #33, moving `pymsrc` script tags to `wp_footer`
- Fixes #35, moving `new pym.Parent` tags to `wp_footer`
- If a post has differing pymsrc values, output a warning to the page console.log (if console.log exists, that is; gotta support IE 9 since Pym.js does)
- If a post has differing pymsrc values, output a warning to the server log if WP_DEBUG
- Adds a singleton class Pymsrc_Output to manage all of that.
@benlk
Copy link
Collaborator Author

benlk commented Aug 31, 2018

On the subject of the browser console errors, hard to tell.

  • the block should save something in the post content that isn't just an empty block. Like, at barest minimum, the URL.

It's disconcerting to deactivate the plugin and see nothing where a block used to be, just an empty "Classic" editor.

This was referenced Aug 31, 2018
@benlk
Copy link
Collaborator Author

benlk commented Aug 31, 2018

…amount of its documentation.

Fixes #19

Making this output function something that people can replace
is simpler than having to store arbitrary HTML input in a settings page.
…ve translation files available at the moment.

see #40
@benlk
Copy link
Collaborator Author

benlk commented Aug 31, 2018

Internationalization is blocked by insufficient Gutenberg docs; see #40.

@benlk
Copy link
Collaborator Author

benlk commented Aug 31, 2018

Okay, state of this PR:

Changes

  • Adds a "Pym Embed" block for use in Gutenberg. PR #34 for issue #28.
  • Shortcode now gains an align="" parameter, so that WordPress's generated alignment CSS classes can be used on embeds. By enabling this in the shortcode, the Gutenberg Block also gains support for alignment. PR #34
  • Script tags for embeds are no longer output by the_content(), instead being output during wp_footer() by closures hooked on the 'wp_footer' action. PR #34 for issues #33 and #35.
  • The source URL for pym.js is no longer output by the_content(), instead being output during wp_footer by an action dedicated to the task. If different shortcodes and/or blocks on the page specify different source URLs for Pym.js, all are output (after removing duplicates), but a message is logged in the browser console. If WP_DEBUG is set, this message is also logged to the server log, with the post ID specified. PR #34 for issues #33 and #35. See https://github.com/INN/pym-shortcode/tree/master/docs#ive-set-a-different-pymsrc-option-but-now-im-seeing-a-message-in-the-console
  • The script tag used to run new pym.Parent is now configurable. By replacing the pluggable function pym_shortcode_script_footer_enqueue() with your own function, you can now use alternate forms of embed code that may be required for PJAX sites or custom versions of Pym.js. This resolves issue #19.
  • Docs improvements:
    • docs in README.md are merged into the docs in docs/readme.md.
    • all parameters of the shortcode/block are now documented
    • new and improved content hierarchy in the docs

New issues created

to be addressed before the next release

deferred

@benlk
Copy link
Collaborator Author

benlk commented Aug 31, 2018

Changes to docs:

  • TOC
  • flag the one required option vs the many optional options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants