2

I have a listener for the entries.saveEntryevent that is calling a service, which generates an email from a rendered template. The template is attempting to import macros.

MyaddonPlugin.php::init()

craft()->on('entries.saveEntry', function(Event $event) {
    if ($event->params['isNewEntry']) {
        craft()->myaddon_emails->generateEmail($event->params['entry']);
    }
});

Myaddon_EmailsService.php::generateEmail()

$emailHtml = craft()->templates->render('myaddon/email');

plugins/myaddon/templates/email.twig

{% import '_macros/mymacro' as mymacro % }

When I attempt to run this I get this error:

Unable to find the template “_macros/mymacro”.

When running the same service/render code from a Controller, everything works. It seems like there is a difference with how paths are set or handled in a Controller vs. an event handler. I tried manually setting the template path based on this page, but same results.

Any thoughts on how to resolve this?

Thanks in advance!

  • I'm not sure if this will help...but try renaming the .twig files as .html. – Aaron Berkowitz Feb 15 '15 at 15:45
  • @aberkie - thanks for the suggestion, but that didn't help either. The strange thing is all of this works through a Controller, so my suspicion is that it has something to do with how paths are handled or loaded in Controllers vs. event handlers. – Nick Le Guillou Feb 16 '15 at 15:59
2

Not 100% sure what is going wrong here, but here is what I would do to debug this on my end:

  1. Simply output the current path the template parser is using in the controller and event handler to see the difference in the values

    var_dump(craft()->path->getTemplatesPath());
    exit();
    
  2. If the values are different, you can override the value to do your parsing as your need it like so:

    // Get the current path and save it
    $oldPath = craft()->path->getTemplatesPath();
    
    // Set your desired template path
    craft()->path->setTemplatesPath('your/new/path');
    
    // Render your template and pass some data to it that will be parsed
    craft()->templates->render('your/template', $data = array());
    
    // Set the old path so Craft can resume as normal and you don't break stuff
    craft()->path->setTemplatesPath($oldPath);
    
  3. One other option is to try to include your macro like so:

    {% import 'myplugin/_macros/mymacro' as mymacro % }
    

I basically do the exact same thing you are doing with Postmaster for Craft. I include my own macros, parse templates and strings during event handlers, it all works perfectly for me using the technique I outlined above. Feel free to take a look at my code if you want to see some more advanced examples of this.

On a side note, I bet Postmaster will do exactly what you want to do in regards to sending an email for new entries. You should give it a shot, it has loads of additional features I bet you could use. No less, I do help this solve your problem either way. Sorry this wasn't really an official answer or a guaranteed fix, but I gave it my best shot without seeing all of your code.

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.