Can kirbytags be used to automatically create a new page?

Hi there,

I am new to Kirby. I am working on building a kirbytag. When invoked, I would like it to create a grandchild page within a particular subpage of the current page. The reason I want this functionality, is that I am having certain words in my text that can be hovered or selected to get more information, like a definition, about them. I need the grandchild page to store this extra information.

In the creating of this kirbytag, I would like to indicate the subpage name wherein to create the grandchild page. This particular subpage name will always exist for the pages I will use the kirbytag on, because I have it being created by the subpage builder.

Point being, in the instructions for making your own kirbytag, it only shows how to make it as a link. Is there a way to have a kirbytag automatically create a new page when invoked? Or some other method to accomplish my needs? The page to store the definition for the invoked word will need to be able to be created from the panel while creating the current page’s text content.

Thank you!

Hi @liaprins and welcome to Kirby. You can’t use a Kirbytag to create subpages, its purpose is to get rendered as HTML. An option would be to create a custom form field with a button that then creates the subpage (similar to the clonr field, but instead of copying the page, you would create a new page).

Do you need to store a lot of information for the definition? Otherwise maybe just store the information in the tag?

I think the most reliable way would be to create the definition pages manually using the Panel. You can then write a Kirbytag that can be used to reference those pages, e.g.:

(definition: my-definition-page)

The Kirbytag can get the page using the page() function (page('definitions/' . $name)) and display the information.

Let us know in case you need further information.

Thanks for the suggestions, both of you! What I plan to do is what @lukasbestle suggests; it will be no problem to manually create the pages to store the definition content.

However, I’d really like the kirbytag to also do another thing I didn’t ask in my original question (because I was tackling the issues involved one at a time). I need the word invoked by the kirbytag to act as an anchor link for itself/its own definition. So when you click the word in the blog page, it opens the definition part (I will do the hiding/opening part with javascript or similar). Right now I am creating sections per kirbytag’ed word with anchor links to themselves, as an array in the blog page’s .php template file. (These sections also pull the definition content from the appropriate grandchild page, as talked about originally.)

There is a problem, because it just makes a list of them at the bottom of the blog article. I am linking to the word’s anchor link with the kirbytag, but it just jumps to the place the same word appears in this list after the article.

I need a way for the kirbytag to create the anchor link for the word in context (and pull the definition content fromthe grandchild page), rather than how I am creating it via array in the template of the page.

Is this possible? Can I do both within a kirbytag: create an anchor link for the word and pull content from the appropriate grandchild page?

Thanks so much!!!

What I would do is probably something like that:

  1. Have a lexicon page (/lexicon) with a structure field for definitions, or maybe child pages for definitions.
  2. In other pages, in the main content, maybe manually reference a definition’s URL, e.g. you content could look like:
    This is a [paragraph](/lexicon/#paragraph).
  3. In PHP when rendering the page (perhaps in a controller, rather than in a template), parse the main text’s content and retrieve a list of definition slugs (looking for slug in lexicon/#slug). Then retrieve the corresponding content from the lexicon page (or subpages) and feed it to the template as an array.
  4. The goal of step 3 is that you can add the definitions at the bottom of the page in a list, with id attributes like <li id="def-paragraph"><strong>Paragraph:</strong> Definition goes here.</li>.
  5. If you did step 4, when rendering the main text you could change the URLs to /lexicon/#slug to point to #def-slug instead.

So at this point you have a HTML page with highlighted words that link to a definition at the bottom of the page, and the definitions come from a single repository. You can style those internal links in a specific way, too (a[href^="#def-"] { color: green; }).

Then you can enhance that page with JavaScript, first hiding the inline definitions, and revealing them in-place in a tooltip when hovering, focusing and/or clicking the definition link.

If changing the links and inlining the definitions in each page is too much work or not desired, you could skip that part (steps 3-4-5), and make two things:

  1. A /lexicon page with all the definitions.
  2. Maybe a /lexicon.json representation that you can retrieve with JavaScript so that instead of following the links to the lexicon page you can show the definition in the article page.

There are a lot of possible solutions. Try to think about 1) ease of content creation and editing (which should avoid duplicate definitions), 2) a working, accessible plain-HTML-and-HTTP result that lets users read the definitions in some way (going to a different page, or jumping to footnotes or something else), and finally 3) enhancing with JavaScript (make it work with clicks and keyboard navigation too, not just mouseover).

@fvsch Thanks so much for the in-depth response! I have not had a chance to work on this project for a week or so, but just read your suggestion now, and that is actually almost exactly how I have it currently employed.

My one difference is I am generating the list of definitions at the bottom of the page purely from the children of the /lexicon page (I am having a child page per definition). Whereas in step 3 you say to “parse the main text’s content and retrieve a list of definition slugs”. I am still creating a link within the main text, per defined word using a custom kirbytag, which currently links to the associated definition in the list at the bottom.

Also I am realizing I may be doing step differently. I am creating the URL anchor links with the “#” per defined word in that blog article’s template PHP file, via an array. Then I reference that URL (via its slug) within the main content through my custom kirbytag. Are you suggesting to create the anchor link per defined word within the main text? If so, that is what I cannot figure out how to do!

Does it matter which way the list of definitions is generated? I definitely want to be able to use a tooltip or similar to show the definition at the spot the word appears within the main text (not just at the bottom in a list). Will how the list is generated affect the ability to do this (e.g. with javascript) ?

Thanks very much!!

If you have some content like this:

<div class="article-text">
  <p>This is a cool <a href="#lex-paragraph">paragraph</a>.</p>
  …
</div>
<ul class="lex-footer">
  <li id="lex-paragraph">
    <strong>Paragraph:</strong>
    A distinct section of a piece of writing, usually dealing with a single theme
    and indicated by a new line, indentation, or numbering.
  </li>
  …
</ul>

Nobody stops you from enhancing that basic behavior with JavaScript (and a bit more CSS), for instance with a script that does something like “when hovering or focusing a link that matches a[href^="#lex-"], retrieve the contents of the element that the href points to, remove the <strong> element at the start, and show the remaining content in an absolutely positioned <div> whose position we’re going to compute.”

Writing such a script can take a while, but thankfully there are already many “tooltip” scripts that do something similar, so you could look for one that fits your needs and has a flexible enough API (for instance a plugin that lets you retrieve the content to show yourself, and only deals with creating and positioning — and later discarding — the tooltip element).

That the basics of progressive enhancement, by the way:

  1. First do something with just HTML that makes sense, even if it’s not the ideal experience you’re shooting for (case in point: definitions at the bottom of the text or on a separate page, and links to those definitions in the text).
  2. Then use JS (and some CSS) to enhance that behavior, while still keeping an eye on accessibility (e.g. make it usable with keyboard navigation and not just a mouse pointer). Ideally, test your “enhanced” version with a screen reader, to check that you can still access content easily. If you’re using a “tooltip” JS lib, maybe test it with a screen reader beforehand.

Perfect, thanks very much! That has been my approach: to make as functional as conceivably possible with html alone. Then add extra refinement with CSS, and if needed JS. I don’t know javascript yet, so wasn’t sure on limits for this. And totally agree about accessibility, so glad other people are promoting it, too! :slight_smile:

Thanks!