$site in a Kirbytext extension

So… yeah, never tried digging into tags before but I did run into scope issues with controllers and snippets, and it’s about time I seriously tackled this weakness of mine.

How does one handle page variables from within things that aren’t templates (ie tags, controllers, etc.)? Also, how to wield scope on the home page?

For instance, I’m trying to create a turbo tag that creates a canvas and ties it to a javascript file. It needs to be able to handle four attributes (with two of these being able to take a default value):

  • turbo (the javascript file’s name)
  • canvas (canvas id)
  • (optional) width (defaults to 720)
  • (optional) height (defaults to 540)
<?php
kirbytext::$tags['turbo'] = array(
  'attr' => array(
    'canvas',
    'width',
    'height'
  ),
  'html' => function($tag) {

    $turbo = $tag->attr('turbo');
    $baseurl = kirby()->site()->url() . '/';
    $url = $baseurl .  $turbo;
    $canvas = $tag->attr('canvas');
    $width = $tag->attr('width', 720);
    $height = $tag->attr('height', 540);

    return '<script src="' . $url . '"></script><canvas id="' . $canvas . '" width=' . $width . ' height= ' . $height . '>';
  }
);

I haven’t done extensive testing yet, but so far: this breaks on the homepage (based on the code I’m seeing, it should work just fine on individual pages). Homepage url is [site]/, rather than [site]/home (which is where the folder is located), and this makes this code useless at displaying a canvas on the homepage (because the $url variable is [site].$turbo instead of [site]./content/home/.$turbo).

Ideally, I’d like for this kind of tag to work independently from current context. If there’s a canvas on page1, i need to be able to see it from home (which renders page1) and from page1. If there’s a canvas on home, I should be able to see it too.

Is there a simple way to achieve this? If it comes to the worst, I can probably build a function that analyses context and determines what to do from there, but that seems way too complicated for such a (I think) simple objective.

Thanks for reading and stuff,
Cheers!

Maybe you could use $page->diruri() https://getkirby.com/docs/cheatsheet/page/diruri?

Hmm… this works on home, but not on page1. But this is already a step forward, thanks!

Try

$baseurl = $tag->page()->contentUrl() . '/';

Actually, same problem as above - I get “[site]/content/2-projects/1-project-a/turbo.js” instead of “[site]/content/projects/project-a/turbo.js” in page1 (working with the base build for now). Is there a way to strip the folder numbers from contentUrl()?

Oh, yes, of course, my bad :blush:

New try:

 $baseurl = url() . '/'. $tag->page()->uri() . '/';

What about this:

$baseurl = $tag->page()->url() . '/';

does not work for the home page …:pensive:

1 Like

Oh, yes. That’s true. :slight_smile:

Okay, now we’re talking!

I have something that works on Home and Page1 (so supposedly everywhere). Now I just need to check whether Page1 read from, say, Page2 can still display Page1’s canvas.

Thanks a lot!

That should work as long as you don’t use the same id more than once in a page.