Jump to content

Hook to page render from a Textformatter


Mike Rockett
 Share

Recommended Posts

With Typographer, I need to be able to inject a script into a page but only if that page has a field that has the Typographer formatter applied to it. The module needs to apply the hook if two conditions are met. The issue is that the hook is indeed added, but it is never called. The only thing I can think of is that it might be too late to add the hook.

Here's how I'm doing it:

    /**
     * Textformatter formatValue (Typographer handler)
     * @param  Page   $page
     * @param  Field  $field
     * @param  string &$value
     * @return void
     */
    public function formatValue(Page $page, Field $field, &$value)
    {
        // ... vendor stuff

        // Run Typographer and return the converted input.
        $value = $this->typographer($value);

        // If configured, add the clipboard-cleaning script
        if ($this->cleanClipboard && !empty($this->hyphenationLanguage)) {
            $page->addHookAfter('render', new CleanClipboardHook());
            // $this->dd($page->getHooks());
            // ^^ this dumps the hooks so we can see that our new hook is there (see below)
        }
    }

And here's the hook data from the dd call above (collapsed for post-brevity):

Spoiler

array(1) {
  [0]=>
  array(4) {
    [0]=>
    array(6) {
      ["id"]=>
      string(13) ":100.0:render"
      ["method"]=>
      string(6) "render"
      ["toObject"]=>
      NULL
      ["toMethod"]=>
      object(Typographer\CleanClipboardHook)#290 (0) {
      }
      ["toPublic"]=>
      bool(true)
      ["options"]=>
      array(8) {
        ["type"]=>
        string(6) "method"
        ["before"]=>
        bool(false)
        ["after"]=>
        bool(true)
        ["priority"]=>
        string(5) "100.0"
        ["allInstances"]=>
        bool(false)
        ["fromClass"]=>
        string(0) ""
        ["argMatch"]=>
        NULL
        ["objMatch"]=>
        NULL
      }
    }
    ["1.0"]=>
    array(6) {
      ["id"]=>
      string(15) "Page:1.0:render"
      ["method"]=>
      string(6) "render"
      ["toObject"]=>
      object(ProcessWire\PageRender)#93 (1) {
        ["data"]=>
        array(1) {
          ["clearCache"]=>
          int(1)
        }
      }
      ["toMethod"]=>
      string(16) "beforeRenderPage"
      ["toPublic"]=>
      bool(true)
      ["options"]=>
      array(8) {
        ["type"]=>
        string(6) "method"
        ["before"]=>
        bool(true)
        ["after"]=>
        bool(false)
        ["priority"]=>
        string(3) "1.0"
        ["allInstances"]=>
        bool(true)
        ["fromClass"]=>
        string(4) "Page"
        ["argMatch"]=>
        NULL
        ["objMatch"]=>
        NULL
      }
    }
    ["100.0"]=>
    array(6) {
      ["id"]=>
      string(17) "Page:100.0:render"
      ["method"]=>
      string(6) "render"
      ["toObject"]=>
      object(ProcessWire\PageRender)#93 (1) {
        ["data"]=>
        array(1) {
          ["clearCache"]=>
          int(1)
        }
      }
      ["toMethod"]=>
      string(10) "renderPage"
      ["toPublic"]=>
      bool(true)
      ["options"]=>
      array(8) {
        ["type"]=>
        string(6) "method"
        ["before"]=>
        bool(false)
        ["after"]=>
        bool(true)
        ["priority"]=>
        string(5) "100.0"
        ["allInstances"]=>
        bool(true)
        ["fromClass"]=>
        string(4) "Page"
        ["argMatch"]=>
        NULL
        ["objMatch"]=>
        NULL
      }
    }
    ["100.1"]=>
    array(6) {
      ["id"]=>
      string(17) "Page:100.1:render"
      ["method"]=>
      string(6) "render"
      ["toObject"]=>
      object(ProcessWire\LanguageSupportPageNames)#83 (1) {
        ["data"]=>
        array(4) {
          ["moduleVersion"]=>
          int(9)
          ["inheritInactive"]=>
          int(0)
          ["useHomeSegment"]=>
          int(0)
          ["pageNumUrlPrefix1010"]=>
          string(4) "page"
        }
      }
      ["toMethod"]=>
      string(14) "hookPageRender"
      ["toPublic"]=>
      bool(true)
      ["options"]=>
      array(8) {
        ["type"]=>
        string(6) "method"
        ["before"]=>
        bool(true)
        ["after"]=>
        bool(false)
        ["priority"]=>
        string(5) "100.1"
        ["allInstances"]=>
        bool(true)
        ["fromClass"]=>
        string(4) "Page"
        ["argMatch"]=>
        NULL
        ["objMatch"]=>
        NULL
      }
    }
  }
}

 

I've tried using a both a normal class-method (..., $this, 'hook') and a closure instead of the self-invoking hook class, but it's the same result. Have also toyed around with priority, but to no avail.

Is there perhaps a better way to handle this? Or I am missing something incredibly small and simple here?

Link to comment
Share on other sites

2 hours ago, abdus said:

Just append the script to $value? You don't need to hook page render at that point 

Thanks, but that would mean multiple scripts where there are multiple fields that use Typographer. I'd like to keep it clean, where the scripts are appended at the end of the rendered page. Now that you mentioned it though, using formatValue would actually add the hook more than once anyway (when a page contains multiple fields in use). So perhaps I'd need a hook that runs on page render and checks the page for fields that use Typographer. Also might be best to have a separate module for that to avoid autoloading the textformatter.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...