diff --git a/Config/config.php b/Config/config.php index 9e9816b..57fb563 100644 --- a/Config/config.php +++ b/Config/config.php @@ -28,8 +28,7 @@ 'class' => \MauticPlugin\MauticAdvancedTemplatesBundle\Helper\Twig_Loader_DynamicContent::class, 'arguments' => [ 'monolog.logger.mautic', - 'mautic.model.factory', - 'mautic.helper.dynamicContent' + 'mautic.model.factory' ] ] ] diff --git a/EventListener/EmailSubscriber.php b/EventListener/EmailSubscriber.php index e566136..2e994f9 100644 --- a/EventListener/EmailSubscriber.php +++ b/EventListener/EmailSubscriber.php @@ -34,7 +34,6 @@ public function __construct(TemplateProcessor $templateProcessor) */ public static function getSubscribedEvents() { - $a = 1 / 0; return [ EmailEvents::EMAIL_ON_SEND => ['onEmailGenerate', 0], EmailEvents::EMAIL_ON_DISPLAY => ['onEmailGenerate', 0] diff --git a/Helper/Twig_Loader_DynamicContent.php b/Helper/Twig_Loader_DynamicContent.php index 3ae4dca..95aec47 100644 --- a/Helper/Twig_Loader_DynamicContent.php +++ b/Helper/Twig_Loader_DynamicContent.php @@ -4,7 +4,6 @@ use Mautic\CoreBundle\Factory\ModelFactory; use Mautic\DynamicContentBundle\Entity\DynamicContent; -use Mautic\DynamicContentBundle\Helper\DynamicContentHelper; use Psr\Log\LoggerInterface; use Twig_Error_Loader; use Twig_Source; @@ -21,23 +20,16 @@ class Twig_Loader_DynamicContent implements \Twig_LoaderInterface, \Twig_ExistsL * @var LoggerInterface */ protected $logger; - /** - * @var DynamicContentHelper - */ - private $dynamicContentHelper; /** * Twig_Loader_DynamicContent constructor. * @param LoggerInterface $logger * @param ModelFactory $modelFactory - * @param DynamicContentHelper $dynamicContentHelper */ - public function __construct(LoggerInterface $logger, ModelFactory $modelFactory, DynamicContentHelper $dynamicContentHelper) + public function __construct(LoggerInterface $logger, ModelFactory $modelFactory) { $this->modelFactory = $modelFactory; $this->logger = $logger; - $this->dynamicContentHelper = $dynamicContentHelper; - $logger->debug('Twig_Loader_DynamicContent: created $twigDynamicContentLoader'); } @@ -65,7 +57,6 @@ public function getSource($name) * * @return string The cache key * - * @throws Twig_Error_Loader When $name is not found */ public function getCacheKey($name) { @@ -81,11 +72,11 @@ public function getCacheKey($name) * * @return bool true if the template is fresh, false otherwise * - * @throws Twig_Error_Loader When $name is not found */ public function isFresh($name, $time) { // TODO: Implement isFresh() method. + $this->logger->debug('Twig_Loader_DynamicContent: Is Fresh: ' . $time . ', ' . $name); return false; } @@ -120,7 +111,6 @@ private function aliasForTemplateName($name) private function findTemplate($resourceAlias) { $model = $this->modelFactory->getModel('dynamicContent'); - $this->logger->debug('Twig_Loader_DynamicContent: Loading dynamic content by alias: ' . $resourceAlias); $result = $model->getEntities( [ 'filter' => [ @@ -155,7 +145,6 @@ private function findTemplate($resourceAlias) */ public function exists($name) { - $this->logger->debug('Twig_Loader_DynamicContent: EXISTS called for ' . $name); return $this->supports($name) && $this->findTemplate($this->aliasForTemplateName($name)) !== null; } diff --git a/README.md b/README.md index a027442..bc65bfa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,128 @@ -# mautic-advanced-templates-bundle -Plugin extends default email template capabilities with TWIG block so you can use advanced scripting techniques like conditions, loops etc +# Mautic Advanced Templates Bundle + +Plugin extends default email template capabilities with TWIG block so you can use advanced templating +techniques like conditions, loops etc. + +### Purpose + +For example you need slightly different content of your email depending on the information you already know about +your contact (e.g. country, gender, whatever). Instead of creating tons of very similar emails you can create one with +conditions coded inside. + +Another example - you might want to include dynamic content to your email. For let's say you are implementing +abandoned cart feature and you want your customers to see exact content of their cart. Again, the solution might be to +push cart content in JSON format to your contact via API and then iterate through the items in your template to render +picture, name and price for each one. + +### Compatibility + +This plugin was tested with: + +* Mautic v2.14.2 +* PHP v7.1.23 + +There is a high possibility it is compatible with other environments, but we never tested it. + +### Features + +* TWIG templates could be used in the emails. Just create am email and put your TWIG template between special tags: +```twig +{% TWIG_BLOCK %} +Your template TWIG goes here.... +{% END_TWIG_BLOCK %} +``` +* Reusable TWIG snippets could be loaded form Dynamic content entities. +* TWIG extended with some useful functions and filters (see below). + +## Installation + +1. Download or clone this bundle into your Mautic `/plugins` folder. +2. Delete your cache (`app/cache/prod`). +3. In the Mautic GUI, go to the gear and then to Plugins. +4. Click "Install/Upgrade Plugins". +5. You should see the Advanced Templates Bundle in your list of plugins. + + +## Usage + +Once installed plugin is read to be used (no configuration required). +Shortly saying, the text between `{% TWIG_BLOCK %}` and `{% END_TWIG_BLOCK %}` in your emails will be treated as TWIG +template. Please check out [TWIG official documentation](https://twig.symfony.com/doc/2.x/templates.html) to +familiarize yourself with syntax and capabilities. + +You can also make avoid lot of copy-and-paste with `include()` function available in templates. Just put reusable +pieces of templates into Dynamic Content entity and use refer it in your main email templates (see examples below). + +Note: The context will be shared with included template so each variable available outside will be available in the +included snippet. + +### Context + +Table below explains which variables are exposed to the context. Also it holds the list of extra functions and filters available. Please note, all standard library of tags\filter\functions as per official TWIG documents is available as well. + +| Entity | Type | Description | Example | +| ----------- | -------- | ---------------------------------------- | ---------------------------------------- | +| lead | Variable | Holds a Lead entity (contact). You should refer fields by alias name (see example). | `{{lead.firstname}}`, `{{lead.country}}` | +| json_decode | Filter | Converts string in JSON format into object. | `{% set cart = lead.cart | json_decode %}` In this sample we declare variable `cart` which will hold deserialized cart. | +| | | | | + + + +### Example 1: Basic scenario + +Let's say you'd like to add an extra paragraph about weather in New York for people from that area: + +1. Navigate to the Channels / Emails / New / Builder +2. Open the editor for the slot you need to update (Source code mode is preferable) +3. Put the following inside your template: +```twig +{% TWIG_BLOCK %} +

Hi {{lead.firstname}},

+ {% if lead.city == 'New York' %} +

What a great weather is in New York this week!

+ {% endif %} + +

Main letter content goes here

+{% END_TWIG_BLOCK %} +``` + +### Example 2: Rendering structured data + +Imaging you need to remind your prospect about incomplete purchase (abandoned cart feature). + +We assume you have an integration with your e-commerce software which pushes cart information into Mautic contact +entity in the custom field `cart`. + +Assume cart information is JSON and has the following format: + +```json + [ + {"sku": "123456", "name": "My cool product 1"}, + {"sku": "8574865", "name": "My cool product 2"} + ] +``` + +Thus, in order to render all items you should code something like this: + +```twig +{% TWIG_BLOCK %} + {% set cart = lead.cart | json_decode %} + Your cart: + +{% END_TWIG_BLOCK %} +``` + +## Credits + +Dmitry Berezovsky, Logicify (http://logicify.com/) + +## Disclaimer + +This plug-in is licensed under MIT. This means you are free to use it even in commercial project. + +The MIT license clearly explains that there is no warranty for this free software. +Please see the included [LICENSE](LICENSE) file for details. \ No newline at end of file