From a7c019d658babc6ac9ec1dd489ab201d2c458589 Mon Sep 17 00:00:00 2001 From: Daniel Huf Date: Thu, 14 Dec 2017 14:00:53 +0100 Subject: [PATCH] [TASK] Init --- .gitignore | 14 ++ .../Domain/Finishers/MjmlEmailFinisher.php | 130 ++++++++++++++++++ Classes/View/MjmlBasedView.php | 34 +++++ README.md | 35 ++++- composer.json | 22 +++ ext_conf_template.txt | 11 ++ ext_emconf.php | 32 +++++ ext_icon.svg | 28 ++++ package.json | 6 + 9 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 Classes/Domain/Finishers/MjmlEmailFinisher.php create mode 100644 Classes/View/MjmlBasedView.php create mode 100644 composer.json create mode 100644 ext_conf_template.txt create mode 100644 ext_emconf.php create mode 100644 ext_icon.svg create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a11232f --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# ide +/.project +/.buildpath +/.settings +/.nbproject +/.idea + +# git +/.auth.json + +# node / grunt / sass / bower +.sass-cache +node_modules +bower_components diff --git a/Classes/Domain/Finishers/MjmlEmailFinisher.php b/Classes/Domain/Finishers/MjmlEmailFinisher.php new file mode 100644 index 0000000..dca110e --- /dev/null +++ b/Classes/Domain/Finishers/MjmlEmailFinisher.php @@ -0,0 +1,130 @@ + '', + 'senderName' => '', + 'format' => self::FORMAT_HTML, + 'attachUploads' => true + ]; + + /** + * Executes this finisher + * @see AbstractFinisher::execute() + * + * @throws FinisherException + */ + protected function executeInternal() + { + parent::executeInternal(); + } + + /** + * @param FormRuntime $formRuntime + * @return StandaloneView + * @throws FinisherException + */ + protected function initializeStandaloneView(FormRuntime $formRuntime): StandaloneView + { + $format = ucfirst($this->parseOption('format')); + $standaloneView = $this->objectManager->get(MjmlBasedView::class); + + if (isset($this->options['templatePathAndFilename'])) { + $this->options['templatePathAndFilename'] = strtr($this->options['templatePathAndFilename'], [ + '{@format}' => $format + ]); + $standaloneView->setTemplatePathAndFilename($this->options['templatePathAndFilename']); + } else { + if (!isset($this->options['templateName'])) { + throw new FinisherException('The option "templateName" must be set for the EmailFinisher.', 1327058829); + } + $this->options['templateName'] = strtr($this->options['templateName'], [ + '{@format}' => $format + ]); + $standaloneView->setTemplate($this->options['templateName']); + } + + $standaloneView->assign('finisherVariableProvider', $this->finisherContext->getFinisherVariableProvider()); + + if (isset($this->options['templateRootPaths']) && is_array($this->options['templateRootPaths'])) { + $standaloneView->setTemplateRootPaths($this->options['templateRootPaths']); + } + + if (isset($this->options['partialRootPaths']) && is_array($this->options['partialRootPaths'])) { + $standaloneView->setPartialRootPaths($this->options['partialRootPaths']); + } + + if (isset($this->options['layoutRootPaths']) && is_array($this->options['layoutRootPaths'])) { + $standaloneView->setLayoutRootPaths($this->options['layoutRootPaths']); + } + + if (isset($this->options['variables'])) { + $standaloneView->assignMultiple($this->options['variables']); + } + + $standaloneView->assign('form', $formRuntime); + $standaloneView->getRenderingContext() + ->getViewHelperVariableContainer() + ->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $formRuntime); + + return $standaloneView; + } +} diff --git a/Classes/View/MjmlBasedView.php b/Classes/View/MjmlBasedView.php new file mode 100644 index 0000000..bfbd673 --- /dev/null +++ b/Classes/View/MjmlBasedView.php @@ -0,0 +1,34 @@ +getHtmlFromMjml(parent::render()); + } + + protected function getHtmlFromMjml($mjml) + { + $configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['mjml']); + + $temporaryMjmlFileWithPath = GeneralUtility::tempnam('mjml_', '.mjml'); + $mjmlFile = fopen($temporaryMjmlFileWithPath, 'w'); + fwrite($mjmlFile, $mjml); + fclose($mjmlFile); + + // see https://mjml.io/download and https://www.npmjs.com/package/mjml-cli + $cmd = $configuration['nodeBinaryPath'] . ' ' . $configuration['mjmlBinaryPath'] . $configuration['mjmlBinary'] .' ' . $configuration['mjmlParams'] . ' ' . $temporaryMjmlFileWithPath; + + $result = []; + $returnValue = ''; + CommandUtility::exec($cmd, $result, $returnValue); + + return implode('',$result); + } +} diff --git a/README.md b/README.md index 0f62025..400e2fe 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ -# mjml -TYPO3 Mjml.io integration for EXT:Form +# MJML + +https://mjml.io integration for **TYPO3 EXT:Form** + +MJML is a markup language designed to reduce the pain of coding a responsive email. Its semantic syntax makes it easy and straightforward and its rich standard components library speeds up your development time and lightens your email codebase. MJML’s open-source engine generates high quality responsive HTML compliant with best practices. https://mjml.io/getting-started-onboard + +## Installation + +### Over composer: + +`composer require saccas/mjml` + +### NPM + +Npm is needed for the conversion of the MJML file to HTML + +## Usage in EXT:Form + +You can overwrite the default _finishersEmailMixin_ so that he uses the _MjmlEmailFinisher_ +or create your own. + +``` +TYPO3: + CMS: + Form: + mixins: + finishersEmailMixin: + implementationClassName: 'Saccas\Mjml\Domain\Finishers\MjmlEmailFinisher' +``` + +## MJML Documentation + +https://mjml.io/documentation/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..ddbff51 --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "saccas/mjml", + "description": "Mjml view using mjml over npm", + "type": "typo3-cms-extension", + "version": "1.0.0", + "homepage": "https://mjml.io", + "license": ["GPL-2.0+"], + "autoload": { + "psr-4": { + "Saccas\\Mjml\\": "Classes/" + } + }, + "require": { + "php": ">=7.0.0 <=7.2.99", + "typo3/cms-core": ">=8.7.0,<8.9.99" + }, + "scripts": { + "post-install-cmd": [ + "npm install" + ] + } +} diff --git a/ext_conf_template.txt b/ext_conf_template.txt new file mode 100644 index 0000000..66297a8 --- /dev/null +++ b/ext_conf_template.txt @@ -0,0 +1,11 @@ +# cat=node/Binary/1000; type=string; label=Path to node binary +nodeBinaryPath = /usr/local/bin/node + +# cat=mjml/Binary/2000; type=string; label=Path to mjml binary +mjmlBinaryPath = ../node_modules/.bin/ + +# cat=mjml/Binary/3000; type=string; label=mjml binary +mjmlBinary = mjml + +# cat=mjml/Binary/4000; type=string; label=mjml params +mjmlParams = -s -m diff --git a/ext_emconf.php b/ext_emconf.php new file mode 100644 index 0000000..ae5757c --- /dev/null +++ b/ext_emconf.php @@ -0,0 +1,32 @@ + 'Mjml', + 'description' => 'Mjml view using mjml over npm', + 'category' => 'misc', + 'shy' => 0, + 'version' => '1.0.0', + 'state' => 'stable', + 'clearCacheOnLoad' => 1, + 'author' => '', + 'author_email' => '', + 'author_company' => '', + 'autoload' => + [ + 'psr-4' => ['Saccas\\Mjml\\' => 'Classes'] + ], + 'constraints' => [ + 'depends' => [ + 'php' => '7.0.0-0.0.0', + 'typo3' => '8.7.*', + 'extbase' => '', + ], + 'conflicts' => [ + ], + 'suggests' => [ + ], + ], + '_md5_values_when_last_written' => 'a:0:{}', + 'suggests' => [ + ], +]; diff --git a/ext_icon.svg b/ext_icon.svg new file mode 100644 index 0000000..8a0df96 --- /dev/null +++ b/ext_icon.svg @@ -0,0 +1,28 @@ + + + + +Logo +Created with Sketch. + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..22a03d9 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "name": "mjml-typo3", + "dependencies": { + "mjml": "^3.3.5" + } +}