A blog prob­a­bly of inter­est only to nerds by John F Mor­ton.

Ink of the day: “MIXING…” 

SuperGeekery: A blog probably of interest only to nerds by John F Morton.

Entry Editor Links, a new Craft CMS plugin

Example of the Entry Editor Links plugin. For authorized users, each entry title includes a link to edit the post.

I have pub­lished a new plu­g­in on the Craft CMS plu­g­in store: Entry Edi­tor Links. This plu­g­in is designed to help devel­op­ers quick­ly cre­ate links to an entry’s edit page in the con­trol pan­el for autho­rized users on the front end of a Craft site.

Use Twig instead

If you’re not sta­t­i­cal­ly caching your site, you can achieve a link in your Twig tem­plates and avoid adding anoth­er plu­g­in. One Darn­ley Road­’s starter tem­plate has a con­cise exam­ple of how to cre­ate an edi­tor link in their GitHub repo. I used their tech­nique on my site ini­tial­ly.

Here’s the snip­pet for quick ref­er­ence:

  {# Element edit button
     requires a currentUser, who can access the CP, and the request should not be an iframe live preview #}
  {% if currentUser
        and currentUser.can('accessCp')
        and not (craft.app.request.getIsPreview() and craft.app.request.headers.get('sec-fetch-dest') == 'iframe') %}
    {% html at endBody %}
      {% set element = craft.app.getUrlManager().getMatchedElement() %}
      {% if element and element.canSave(currentUser) %}
        <a href="{{ element.getCpEditUrl() }}"
           target="_blank"
           class="fixed left-0 bg-black text-white bottom-0 px-5 py-2 mb-6 ml-6 font-mono uppercase">
          Edit this page
        </a>
      {% endif %}
    {% endhtml %}
  {% endif %}

As you can see above, the snip­pet will only ren­der the edit link when the logged-in user has per­mis­sion to edit the post and is view­ing the page on the site’s front end.

Static caching is great.

This Twig snip­pet worked for me until I imple­ment­ed FastC­GI Cache, as out­lined in this post by nystudio107. How dos it work? Sta­t­ic page caching ren­ders each page only once, and then, on sub­se­quent vis­its, the pre­vi­ous­ly ren­dered HTML is served instead.

This sta­t­ic cache helps a site per­form well, even an under­pow­ered serv­er, because the serv­er isn’t eval­u­at­ing any­thing most of the time. It just pro­vides a sim­ple HTML doc­u­ment to the user. There is no page log­ic to both­er with.

Static caching is great, but not in all cases.

Using the page you’re read­ing now as an exam­ple, the prob­lem is that if I vis­it this page before you do, the link to edit this entry will be part of the sta­t­i­cal­ly cached page. I’ll see the link to edit this entry, and so will you. Craft CMS is secure, so if you clicked the ​“edit this entry” link, you would not gain access to the site’s back end. You’d be stuck at the login page.

Even so, the edit link should be pre­sent­ed only to me. Ren­der­ing that link to every­one would look like an error (because it would be an error!) and expose infor­ma­tion about the site struc­ture that I don’t want to be exposed.

JavaScript to the rescue

JavaScript allows a page to be altered after it’s ren­dered, and the Entry Edi­tor Links plu­g­in pro­vides a helper method and a sim­ple end­point to query to help make this a easy process.

There are three steps to imple­ment this on your site. (These instruc­tions are also in the doc­u­men­ta­tion for the Entry Edi­tor Links plu­g­in.

  1. Down­load and install the Entry Edi­tor Links plu­g­in. It’s free. :beer:
  2. Add a data attribute, data-edit-link, to the ele­ment that con­tains your entry’s head­line and set the val­ue to the ID of the entry in Craft. The plu­g­in pro­vides a helper method, isFrontEndPageView(), to ensure you’re ren­der­ing the data attribute only to the front end of the page site and not in a pre­view win­dow of the site. This means the full Twig looks like this: {% if isFrontEndPageView() %}data-edit-link="{{ entry.id }}"{% endif %}.
  3. Final­ly, you need some JavaScript that will look through the page for the pres­ence of this data attribute. If you find one or more of them, loop through them, hit­ting the plug­in’s API end­point. This will deter­mine if the user is logged in and if they can edit an entry. If they do, you’ll receive the URL to edit the page in the con­trol pan­el. In the exam­ple JavaScript I pro­vide in the doc­u­men­ta­tion, you’ll cre­ate a new a ele­ment and insert it into the DOM right after the head­line.

Customize the JavaScript

The JavaScript I include in the doc­u­men­ta­tion is only an exam­ple. You may want the edit link to live else­where. You may want it to have dif­fer­ent link text. Change it how­ev­er you want. The exam­ple JS is to get you start­ed.

If you have prob­lems or sug­ges­tions, sub­mit an issue on GitHub. Cheers.