Out of the box, Craft won't even load your _entry.html
file for a disabled entry – it'll just throw a 404.
To work around that, you can create a dynamic route which matches the entry type URL format 1:1, and point that route to the same template (i.e. _entry.html
).
For instance, if your entry type's URL format is news/{postDate.year}/{slug}
, you'd create a dynamic route using the "year" and "slug" tokens (i.e. news/(year)/(slug)
). Then, Craft will automatically match your dynamic route whenever an entry URL doesn't (e.g. when the entry is disabled).
You're not home free yet, though – as you're probably aware, Craft automatically populates a template with an entry
variable whenever the current URL request matches an entry type's URL format, and an enabled entry is found at that URL. This won't be the case for any entries matched by your dynamic route, so put this at the top of your template (replacing the line in your question!):
{% set entry = entry ?? slug ? craft.entries.section('yourSectionHandle').slug(slug).status(null).first() %}
{% if not entry %}
{% exit 404 %}
{% endif %}
What the above does, is to test for the entry
variable Craft would set if the entry was enabled. If that evaluates to false
, then it checks to see if there's a slug
variable set – which there will be if the URL was matched by the dynamic route. If there is a slug, it'll then attempt to pull the entry using craft.entries
, similar to your initial code. Finally, if an entry is not found, it'll throw a 404 error, as it should.
In your template, you can easily test for the entry's status:
{% if not entry.enabled %}
<p>Danger danger! I am disabled!</p>
{% endif %}