Skip to content
This repository has been archived by the owner on Mar 22, 2020. It is now read-only.

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
rennokki committed Aug 5, 2018
0 parents commit 060ffc3
Show file tree
Hide file tree
Showing 11 changed files with 432 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor/
composer.lock
1 change: 1 addition & 0 deletions .styleci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
preset: laravel
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: php

php:
- 7.1
- 7.2

env:
matrix:
- COMPOSER_FLAGS=""

before_script:
- travis_retry composer self-update
- travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source

script:
- phpunit --coverage-text --coverage-clover=coverage.xml

after_success:
- bash <(curl -s https://codecov.io/bash)
18 changes: 18 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
codecov:
notify:
require_ci_to_pass: yes

coverage:
precision: 2
round: down
range: “70…100”

status:
project: yes
patch: yes
changes: no

comment:
layout: “reach, diff, flags, files, footer”
behavior: default
require_changes: no
60 changes: 60 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "rennokki/laravel-mjml",
"description": "Laravel MJML offers support for rendering MJML syntax into in-line HTML that can be sent within mails.",
"keywords": [
"laravel",
"mjml",
"wrapper",
"api",
"mjmlio",
"mails",
"mail",
"email",
"emails",
"template",
"templates"
],
"homepage": "https://github.com/rennokki/laravel-mjml",
"license": "MIT",
"authors": [
{
"name": "Alex Renoki",
"email": "rennokki@gmail.com",
"homepage": "https://twitter.com/rennokki",
"role": "Developer"
}
],
"require": {
"guzzlehttp/guzzle": "^6.3@dev",
"mustache/mustache": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "^6.2|^7.0",
"orchestra/testbench": "~3.5.0|~3.6.0",
"orchestra/database": "~3.5.0|~3.6.0"
},
"autoload": {
"psr-4": {
"Rennokki\\LaravelMJML\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Rennokki\\LaravelMJML\\Test\\": "tests"
}
},
"scripts": {
"test": "vendor/bin/phpunit"
},
"extra": {
"laravel": {
"providers": [
"Rennokki\\LaravelMJML\\LaravelMJMLServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}
22 changes: 22 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Rennokki Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
91 changes: 91 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
[![Build Status](https://travis-ci.org/rennokki/laravel-mjml.svg?branch=master)](https://travis-ci.org/rennokki/laravel-mjml)
[![codecov](https://codecov.io/gh/rennokki/laravel-mjml/branch/master/graph/badge.svg)](https://codecov.io/gh/rennokki/laravel-mjml/branch/master)
[![StyleCI](https://github.styleci.io/repos/143601238/shield?branch=master)](https://github.styleci.io/repos/143601238)
[![Latest Stable Version](https://poser.pugx.org/rennokki/laravel-mjml/v/stable)](https://packagist.org/packages/rennokki/laravel-mjml)
[![Total Downloads](https://poser.pugx.org/rennokki/laravel-mjml/downloads)](https://packagist.org/packages/rennokki/laravel-mjml)
[![Monthly Downloads](https://poser.pugx.org/rennokki/laravel-mjml/d/monthly)](https://packagist.org/packages/rennokki/laravel-mjml)
[![License](https://poser.pugx.org/rennokki/laravel-mjml/license)](https://packagist.org/packages/rennokki/laravel-mjml)

[![PayPal](https://img.shields.io/badge/PayPal-donate-blue.svg)](https://paypal.me/rennokki)

# Laravel MJML
Laravel MJML is a simple API wrapper for the [MJML.io Render API](https://mjml.io/api). In case you don't know what [MJML.io](https://mjml.io) is, it is a language that helps
building mails easier and faster without messing up with inline HTML. It has its own syntax that can be later rendered using their apps, online editor
or their API.

This API wrapper comes with Mustache Engine integrated, so you can both render the MJML to HTML with applied values from Mustache.

If you don't know what Mustache is check [this Medium article](https://medium.com/@alexrenoki/dynamic-content-in-your-mails-using-mustache-9f3a660462ad) that explains better Mustahce and gets you started on how to use it in your email.

# Installation
Install the package:
```bash
$ composer require rennokki/laravel-mjml
```

If your Laravel version does not support package discovery, add this line in the `providers` array in your `config/app.php` file:
```php
Rennokki\LaravelMJML\LaravelMJMLServiceProvider::class,
```

# Setting up the API
Since it is an API, you'll need credentials. For this, you will have to request yours from their API page: [https://mjml.io/api](https://mjml.io/api) by clicking `Join the beta`. It will take some time to get yours, so be patient.

To authenticate the API, you will have to call the `Rennokki\LaravelMJML\LaravelMJML` class and then, by chaining methods, to add your `App ID` and your `Secret Key`.
```php
use Rennokki\LaravelMJML\LaravelMJML;

$api = (new LaravelMJML())->setAppId('app_id')->setSecretKey('secret_key');
```

Note: when making requests from the backend, just the `Secret Key` is required. If you plan to do it from the frontend, you will have to use your provided `Public Key` instead, since storing sensitive credentials in frontend is not possible.

# Starting MJML
As MJML code, we'll use this throughout the readme:
```mjml
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">
Hello World
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
```

# Rendering
When rendering, simply calling the `render()` method will do the work for you:
```php
$html = $api->render($mjml);
```

As a return, you will get the compiled HTML. In case this rendering failed, due to reasons, you will get `null`, for example:
```php
$html = $api->render('<h1>MJML</h1>'); // null
```

# Rendering with Mustache
If you got started with Mustache, you can render the MJML to HTML and then render the Mustache variables in your compiled HTML using the same method.

For this example, our MJML would look like this:
```mjml
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">
{{message}}
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
```

You can call `renderWithMustache` method with MJML and an array which consist the parameters that need to injected:
```php
$html = $api->renderWithMustache($mjml, ['message' => 'Hello World!']);
```
119 changes: 119 additions & 0 deletions src/LaravelMJML.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

namespace Rennokki\LaravelMJML;

use GuzzleHttp\Client as GuzzleClient;

class LaravelMJML {

private $secretKey;
protected $appId;
public $publicKey;

protected $client;
protected $mustache;

public static $apiEndpoint = 'https://api.mjml.io/v1';

public function __construct()
{
$this->client = new GuzzleClient();
$this->mustache = new \Mustache_Engine;
}

/**
* Set the public key.
*
* @param string $publicKey
* @return void
*/
public function setPublicKey(string $publicKey)
{
$this->publicKey = $publicKey;

return $this;
}

/**
* Set the secret key.
*
* @param string $secretKey
* @return void
*/
public function setSecretKey(string $secretKey)
{
$this->secretKey = $secretKey;

return $this;
}

/**
* Set the App ID.
*
* @param string $appId
* @return void
*/
public function setAppId(string $appId)
{
$this->appId = $appId;

return $this;
}

/**
* Getting the request response (in JSON) for rendering MJML.
*
* @param string $mjml
* @return string
*/
public function renderRequest(string $mjml)
{
try {
$request = $this->client->request('POST', Self::$apiEndpoint.'/render', [
'auth' => [$this->appId, $this->secretKey],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
'Accepts' => 'application/json'
],
\GuzzleHttp\RequestOptions::JSON => [
'mjml' => $mjml,
],
]);
} catch(\GuzzleHttp\Exception\ClientException $e) {
return json_decode($e->getResponse()->getBody()->getContents());
}

return json_decode($request->getBody());
}

/**
* Getting the rendered HTML for a specified MJML.
*
* @param string $mjml
* @return string|null
*/
public function render(string $mjml)
{
$request = $this->renderRequest($mjml);

if(property_exists($request, 'status_code') && $request->status_code != 200) {
return null;
}

return $request->html;
}

/**
* Rendering the MJML given and apllying mustache render on it.
*
* @param string $mjml
* @param array $parameters
* @return string|null
*/
public function renderWithMustache(string $mjml, array $parameters = [])
{
$html = $this->render($mjml);

return $this->mustache->render($html, $parameters);
}
}
28 changes: 28 additions & 0 deletions src/LaravelMJMLServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rennokki\LaravelMJML;

use Illuminate\Support\ServiceProvider;

class LaravelMJMLServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}

/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
Loading

0 comments on commit 060ffc3

Please sign in to comment.