2

Note: this question pertains to Craft 2 Pro. Craft 3 is not currently an option.

What I need to do

I have some stand-alone utilities that don't need to exist within the Craft framework, so I would really rather not have to go down the road of learning how to develop Craft extensions.

The trick is that these stand-alone utilities do their thing, and then redirect the user to various Craft entries, and I need some way to send arbitrary status messages from the standalone utilities that can then be displayed by the Craft templates.

Example Scenario

We are using a external utility for online fundraising. The user starts on a page that exists as a Craft entry ('Donate'), proceeds to the external utility's web space, and is sent back to the Craft site.

If something goes wrong in the transaction, I need to be able to display any number of error messages to the user, on the original Craft entry, allowing the user to try the donation again. I don't want to create multiple copies of the original Craft entry, one for each possible error message. That seems like an unreasonable duplication of effort and data, and a nightmare in the making if any changes need to be made to what the user sees.

What I hoped would be possible

The external utilities exist on the same domain, so I hoped I might be able to use PHP's $_SESSION variable to set the status message, and then have the Twig template display the message.

Based on what I found, it seems that Twig (at least in Craft 2) doesn't have access to $_SESSION without editing the Craft application code to create a new global variable corresponding to $_SESSION. I want to avoid editing Craft application code to ensure that nothing gets clobbered by updates to Craft.

What to do?

How can I send arbitrary external messages to a Craft entry so that they can be displayed by the Twig template? I don't think I know Craft well enough to know all the possibilities, and so I am not even sure how to search well for what other people have done.

I hope that writing my own extension isn't the answer to this because I haven't figured out how to do that, yet!

Update!

I went ahead with what was recommended in the "accepted answer" below, and it has worked. Here are the steps that I took:

  1. Add a custom route in config/routes.php that looks like this:
    '(?:[-a-zA-Z0-9@:%_\+.~#?&\/=]+\/)+error/(\d+)' => '_entry',
    This matches any URI that ends with /error/ and a number, and will capture the number as a variable. For an explanation of the regex, here it is on regex101.com.
    Note: The version on regex101.com needs one of the forward slashes escaped, but that slash in config/routes.php should not be escaped.

  2. Create a macro that will look up and return the correct error message by using a switch statement on the error number, which will be captured in the matches variable. The macro looks like this:

{% macro show_error(error_id) %}
  {% switch error_id %}
    {% case 10072 %} Error: bad transaction, please try again
    {% default %} Error: error message not found
  {% endswitch %}
{% endmacro %}
  1. Add code at the beginning of _entry to detect if the matches variable exists, and then:

    • look up what entry would have been loaded by the CraftCMS engine, if this weren't a custom route: {% set entry = craft.entries.uri(matches[0]).first() %}
    • save the error message to a variable, using the previously defined macro: {% set error_message = show_error(matches[1]) %}
  2. Display the error message at the appropriate place in the template:

{% if error_message is defined and error_message|length %}
  <div class="error">{{ error_message }}</div>
{% endif %}`
  1. Result: I can append /error/123 to any entry's URI, and the _entry template will be able to integrate the externally-chosen error message in an internal template.
2

Probably the easiest way to do this would be to add another segment to your URI. i.e /bla/bla/bla/message-1 Then in your template, read the segment and display the appropriate message. You could do it all in the template with a switch or conditional or the segment could be the entry slug for the message and you can pull from Craft entries.

1
  • I can work with that! It's not quite "arbitrary message" but I could use a macro in the base layout template, and just add any error messages I ever need to the "errors" macro. And it's probably more advisable to do it that way, anyway, rather than allowing arbitrary input, no matter how much I trust my own programming. ;) – nmjk Jun 1 '18 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.