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:
Add a custom route in
config/routes.phpthat 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 inconfig/routes.phpshould not be escaped.Create a macro that will look up and return the correct error message by using a
switchstatement on the error number, which will be captured in thematchesvariable. 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 %}
Add code at the beginning of
_entryto detect if thematchesvariable 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]) %}
- look up what entry would have been loaded by the CraftCMS engine, if this weren't a custom route:
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 %}`
- Result: I can append
/error/123to any entry's URI, and the_entrytemplate will be able to integrate the externally-chosen error message in an internal template.