Menu icon Foundation

Designer | Cleveland, OH

I make things for space people.

My Posts


My Comments

Thomas Rowley commented on Henrique Zambonin's post about 3 years

Great idea Rafi, I think that this would be a fantastic addition. Thank you for the update.

Thomas Rowley commented on Henrique Zambonin's post about 3 years

Here is my complete gulpfile.babel.js file. Is this correct file to be modifying?
import gulp from 'gulp';
import plugins from 'gulp-load-plugins';
import browser from 'browser-sync';
import rimraf from 'rimraf';
import panini from 'panini';
import yargs from 'yargs';
import lazypipe from 'lazypipe';
import inky from 'inky';
import fs from 'fs';
import siphon from 'siphon-media-query';
import path from 'path';
import merge from 'merge-stream';
import beep from 'beepbeep';
import colors from 'colors';

const $ = plugins();

// Look for the --production flag
const PRODUCTION = !!(yargs.argv.production);

// Declar var so that both AWS and Litmus task can use it.
var CONFIG;

// Build the "dist" folder by running all of the above tasks
gulp.task('build',
gulp.series(clean, pages, sass, images, inline));

// Build emails, run the server, and watch for file changes
gulp.task('default',
gulp.series('build', server, watch));

// Build emails, then send to litmus
gulp.task('litmus',
gulp.series('build', creds, aws, litmus));

// Build emails, then zip
gulp.task('zip',
gulp.series('build', zip));

// Delete the "dist" folder
// This happens every time a build starts
function clean(done) {
rimraf('dist', done);
}

// Compile layouts, pages, and partials into flat HTML files
// Then parse using Inky templates
function pages() {
return gulp.src('src/pages/*/.html')
.pipe(panini({
root: 'src/pages',
layouts: 'src/layouts',
partials: 'src/partials',
helpers: 'src/helpers'
}))
.pipe(inky())
.pipe(gulp.dest('dist'));
}

// Reset Panini's cache of layouts and partials
function resetPages(done) {
panini.refresh();
done();
}

// Compile Sass into CSS
function sass() {
return gulp.src('src/assets/scss/app.scss')
.pipe($.if(!PRODUCTION, $.sourcemaps.init()))
.pipe($.sass({
includePaths: ['node_modules/foundation-emails/scss']
}).on('error', $.sass.logError))
.pipe($.if(!PRODUCTION, $.sourcemaps.write()))
.pipe(gulp.dest('dist/css'));
}

// Copy and compress images
function images() {
return gulp.src('src/assets/img/*/')
.pipe($.imagemin())
.pipe(gulp.dest('./dist/assets/img'));
}

// Inline CSS and minify HTML
function inline() {
return gulp.src('dist/*/.html')
.pipe($.if(PRODUCTION, inliner('dist/css/app.css')))
.pipe(gulp.dest('dist'));
}

// Start a server with LiveReload to preview the site in
function server(done) {
browser.init({
server: 'dist'
});
done();
}

// Watch for file changes
function watch() {
gulp.watch('src/pages//*.html').on('change', gulp.series(pages, inline, browser.reload));
gulp.watch(['src/layouts/
/', 'src/partials//']).on('change', gulp.series(resetPages, pages, inline, browser.reload));
gulp.watch(['../scss//*.scss', 'src/assets/scss//.scss']).on('change', gulp.series(resetPages, sass, pages, inline, browser.reload));
gulp.watch('src/assets/img/
/').on('change', gulp.series(images, browser.reload));
}

// Inlines CSS into HTML, adds media query CSS into the <style> tag of the email, and compresses the HTML
function inliner(css) {
var css = fs.readFileSync(css).toString();
// where fontsFilePath is relative path to a file with @font-face declarations
var fonts = fs.readFileSync('src/assets/css/fonts.css').toString();
var mqCss = siphon(css);

var pipe = lazypipe()
.pipe($.inlineCss, {
applyStyleTags: false
})
// include both fonts and mqCss in the style tags
.pipe($.injectString.replace, '<!-- <style> -->', &lt;style&gt;${fonts}${mqCss}&lt;/style&gt;)
.pipe($.htmlmin, {
collapseWhitespace: true,
minifyCSS: true
});

return pipe();
}

// Ensure creds for Litmus are at least there.
function creds(done) {
var configPath = './config.json';
try { CONFIG = JSON.parse(fs.readFileSync(configPath)); }
catch(e) {
beep();
console.log('[AWS]'.bold.red + ' Sorry, there was an issue locating your config.json. Please see README.md');
process.exit();
}
done();
}

// Post images to AWS S3 so they are accessible to Litmus test
function aws() {
var publisher = !!CONFIG.aws ? $.awspublish.create(CONFIG.aws) : $.awspublish.create();
var headers = {
'Cache-Control': 'max-age=315360000, no-transform, public'
};

return gulp.src('./dist/assets/img/*')
// publisher will add Content-Length, Content-Type and headers specified above
// If not specified it will set x-amz-acl to public-read by default
.pipe(publisher.publish(headers))

// create a cache file to speed up consecutive uploads
//.pipe(publisher.cache())

// print upload updates to console
.pipe($.awspublish.reporter());

}

// Send email to Litmus for testing. If no AWS creds then do not replace img urls.
function litmus() {
var awsURL = !!CONFIG && !!CONFIG.aws && !!CONFIG.aws.url ? CONFIG.aws.url : false;

return gulp.src('dist/*/.html')
.pipe($.if(!!awsURL, $.replace(/=('|")(\/?assets\/img)/g, "=$1"+ awsURL)))
.pipe($.litmus(CONFIG.litmus))
.pipe(gulp.dest('dist'));
}

// Copy and compress into Zip
function zip() {
var dist = 'dist';
var ext = '.html';

function getHtmlFiles(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
var fileExt = path.join(dir, file);
var isHtml = path.extname(fileExt) == ext;
return fs.statSync(fileExt).isFile() && isHtml;
});
}

var htmlFiles = getHtmlFiles(dist);

var moveTasks = htmlFiles.map(function(file){
var sourcePath = path.join(dist, file);
var fileName = path.basename(sourcePath, ext);

var moveHTML = gulp.src(sourcePath)
  .pipe($.rename(function (path) {
    path.dirname = fileName;
    return path;
  }));

var moveImages = gulp.src(sourcePath)
  .pipe($.htmlSrc({ selector: 'img'}))
  .pipe($.rename(function (path) {
    path.dirname = fileName + '/assets/img';
    return path;
  }));

return merge(moveHTML, moveImages)
  .pipe($.zip(fileName+ '.zip'))
  .pipe(gulp.dest('dist'));

});

return merge(moveTasks);
}

Thomas Rowley commented on Henrique Zambonin's post about 3 years

It still doesn't seem to work for me. I must be doing something wrong. When I run the npm build, I get the error in terminal:
[09:52:47] 'inline' errored after 545 ms
[09:52:47] TypeError: Cannot read property 'replace' of undefined
    at inliner (gulpfile.babel.js:119:11)
    at inline (gulpfile.babel.js:87:28)
    at bound (domain.js:254:14)
    at runBound (domain.js:267:12)
    at asyncRunner (/Users/trowley/Desktop/projects/email/campaigns/eye_safety/node_modules/async-done/index.js:36:18)
    at process._tickDomainCallback (node.js:381:11)
[09:52:47] 'build' errored after 5.89 s
[09:52:47] 'default' errored after 5.89 s
 
npm ERR! Darwin 14.5.0
npm ERR! argv "node" "/usr/local/bin/npm" "run" "build"
npm ERR! node v0.12.7
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! foundation-emails-template@1.0.0 build: gulp --production
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the foundation-emails-template@1.0.0 build script 'gulp --production'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the foundation-emails-template package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp --production
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs foundation-emails-template
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls foundation-emails-template
npm ERR! There is likely additional logging output above.
 
npm ERR! Please include the following file with any support request:
 
npm ERR!     /Users/trowley/Desktop/projects/email/campaigns/eye_safety/npm-debug.log

Thomas Rowley commented on zacbrown@me.com's post about 3 years

Can I please have an invite?

Thomas Rowley commented on Henrique Zambonin's post about 3 years

I tried the fix several times and continue to get an error when I am attempting to launch npm run build. Is there anyone would could post their gulp file code here to ensure that I am not having an issue. I continue to get an error on the replace function. 

Thomas Rowley commented on Henrique Zambonin's post about 3 years

 Thank you @Corey, I didn't see that in the original thread. Much appreciated!

Thomas Rowley commented on Henrique Zambonin's post about 3 years

I am having a similar issue to this. I have tried both methods, and during the inline process it removes it. I manually added it to the inline version and it worked. Was there ever a solution found for this?

Thomas Rowley commented on Thomas Rowley's post about 3 years

One small note, now all elements such as &nbsp; and &raquo; are converting the am-percent to &amp; instead of leaving them. Not a huge deal, just figured I would mention it. 

Thomas Rowley commented on Thomas Rowley's post about 3 years

Hello Rafi, 
Initially, it did not work, however, after I did the update and made the change from zurb/inky to zurb/inky#develop it worked perfectly. Here is a screenshot showing it working correctly at this time. 

Thank you again for all of your help!
 
- Thomas

Thomas Rowley commented on Thomas Rowley's post about 3 years

Rafi, 
Thank you for responding. Unfortunately, this did not fix the issue. The valign only an attribute that applies to the <td> tag, and since all of the the updated output code produces <th> to store the data, they do not work. Additionally, I looked at the output code, and valign: middle does not exist anywhere in the code. 
 

Posts Followed



Following

    No Content

Followers

My Posts

My Comments

You commented on Henrique Zambonin's post about 3 years

Great idea Rafi, I think that this would be a fantastic addition. Thank you for the update.

You commented on Henrique Zambonin's post about 3 years

Here is my complete gulpfile.babel.js file. Is this correct file to be modifying?
import gulp from 'gulp';
import plugins from 'gulp-load-plugins';
import browser from 'browser-sync';
import rimraf from 'rimraf';
import panini from 'panini';
import yargs from 'yargs';
import lazypipe from 'lazypipe';
import inky from 'inky';
import fs from 'fs';
import siphon from 'siphon-media-query';
import path from 'path';
import merge from 'merge-stream';
import beep from 'beepbeep';
import colors from 'colors';

const $ = plugins();

// Look for the --production flag
const PRODUCTION = !!(yargs.argv.production);

// Declar var so that both AWS and Litmus task can use it.
var CONFIG;

// Build the "dist" folder by running all of the above tasks
gulp.task('build',
gulp.series(clean, pages, sass, images, inline));

// Build emails, run the server, and watch for file changes
gulp.task('default',
gulp.series('build', server, watch));

// Build emails, then send to litmus
gulp.task('litmus',
gulp.series('build', creds, aws, litmus));

// Build emails, then zip
gulp.task('zip',
gulp.series('build', zip));

// Delete the "dist" folder
// This happens every time a build starts
function clean(done) {
rimraf('dist', done);
}

// Compile layouts, pages, and partials into flat HTML files
// Then parse using Inky templates
function pages() {
return gulp.src('src/pages/*/.html')
.pipe(panini({
root: 'src/pages',
layouts: 'src/layouts',
partials: 'src/partials',
helpers: 'src/helpers'
}))
.pipe(inky())
.pipe(gulp.dest('dist'));
}

// Reset Panini's cache of layouts and partials
function resetPages(done) {
panini.refresh();
done();
}

// Compile Sass into CSS
function sass() {
return gulp.src('src/assets/scss/app.scss')
.pipe($.if(!PRODUCTION, $.sourcemaps.init()))
.pipe($.sass({
includePaths: ['node_modules/foundation-emails/scss']
}).on('error', $.sass.logError))
.pipe($.if(!PRODUCTION, $.sourcemaps.write()))
.pipe(gulp.dest('dist/css'));
}

// Copy and compress images
function images() {
return gulp.src('src/assets/img/*/')
.pipe($.imagemin())
.pipe(gulp.dest('./dist/assets/img'));
}

// Inline CSS and minify HTML
function inline() {
return gulp.src('dist/*/.html')
.pipe($.if(PRODUCTION, inliner('dist/css/app.css')))
.pipe(gulp.dest('dist'));
}

// Start a server with LiveReload to preview the site in
function server(done) {
browser.init({
server: 'dist'
});
done();
}

// Watch for file changes
function watch() {
gulp.watch('src/pages//*.html').on('change', gulp.series(pages, inline, browser.reload));
gulp.watch(['src/layouts/
/', 'src/partials//']).on('change', gulp.series(resetPages, pages, inline, browser.reload));
gulp.watch(['../scss//*.scss', 'src/assets/scss//.scss']).on('change', gulp.series(resetPages, sass, pages, inline, browser.reload));
gulp.watch('src/assets/img/
/').on('change', gulp.series(images, browser.reload));
}

// Inlines CSS into HTML, adds media query CSS into the <style> tag of the email, and compresses the HTML
function inliner(css) {
var css = fs.readFileSync(css).toString();
// where fontsFilePath is relative path to a file with @font-face declarations
var fonts = fs.readFileSync('src/assets/css/fonts.css').toString();
var mqCss = siphon(css);

var pipe = lazypipe()
.pipe($.inlineCss, {
applyStyleTags: false
})
// include both fonts and mqCss in the style tags
.pipe($.injectString.replace, '<!-- <style> -->', &lt;style&gt;${fonts}${mqCss}&lt;/style&gt;)
.pipe($.htmlmin, {
collapseWhitespace: true,
minifyCSS: true
});

return pipe();
}

// Ensure creds for Litmus are at least there.
function creds(done) {
var configPath = './config.json';
try { CONFIG = JSON.parse(fs.readFileSync(configPath)); }
catch(e) {
beep();
console.log('[AWS]'.bold.red + ' Sorry, there was an issue locating your config.json. Please see README.md');
process.exit();
}
done();
}

// Post images to AWS S3 so they are accessible to Litmus test
function aws() {
var publisher = !!CONFIG.aws ? $.awspublish.create(CONFIG.aws) : $.awspublish.create();
var headers = {
'Cache-Control': 'max-age=315360000, no-transform, public'
};

return gulp.src('./dist/assets/img/*')
// publisher will add Content-Length, Content-Type and headers specified above
// If not specified it will set x-amz-acl to public-read by default
.pipe(publisher.publish(headers))

// create a cache file to speed up consecutive uploads
//.pipe(publisher.cache())

// print upload updates to console
.pipe($.awspublish.reporter());

}

// Send email to Litmus for testing. If no AWS creds then do not replace img urls.
function litmus() {
var awsURL = !!CONFIG && !!CONFIG.aws && !!CONFIG.aws.url ? CONFIG.aws.url : false;

return gulp.src('dist/*/.html')
.pipe($.if(!!awsURL, $.replace(/=('|")(\/?assets\/img)/g, "=$1"+ awsURL)))
.pipe($.litmus(CONFIG.litmus))
.pipe(gulp.dest('dist'));
}

// Copy and compress into Zip
function zip() {
var dist = 'dist';
var ext = '.html';

function getHtmlFiles(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
var fileExt = path.join(dir, file);
var isHtml = path.extname(fileExt) == ext;
return fs.statSync(fileExt).isFile() && isHtml;
});
}

var htmlFiles = getHtmlFiles(dist);

var moveTasks = htmlFiles.map(function(file){
var sourcePath = path.join(dist, file);
var fileName = path.basename(sourcePath, ext);

var moveHTML = gulp.src(sourcePath)
  .pipe($.rename(function (path) {
    path.dirname = fileName;
    return path;
  }));

var moveImages = gulp.src(sourcePath)
  .pipe($.htmlSrc({ selector: 'img'}))
  .pipe($.rename(function (path) {
    path.dirname = fileName + '/assets/img';
    return path;
  }));

return merge(moveHTML, moveImages)
  .pipe($.zip(fileName+ '.zip'))
  .pipe(gulp.dest('dist'));

});

return merge(moveTasks);
}

You commented on Henrique Zambonin's post about 3 years

It still doesn't seem to work for me. I must be doing something wrong. When I run the npm build, I get the error in terminal:
[09:52:47] 'inline' errored after 545 ms
[09:52:47] TypeError: Cannot read property 'replace' of undefined
    at inliner (gulpfile.babel.js:119:11)
    at inline (gulpfile.babel.js:87:28)
    at bound (domain.js:254:14)
    at runBound (domain.js:267:12)
    at asyncRunner (/Users/trowley/Desktop/projects/email/campaigns/eye_safety/node_modules/async-done/index.js:36:18)
    at process._tickDomainCallback (node.js:381:11)
[09:52:47] 'build' errored after 5.89 s
[09:52:47] 'default' errored after 5.89 s
 
npm ERR! Darwin 14.5.0
npm ERR! argv "node" "/usr/local/bin/npm" "run" "build"
npm ERR! node v0.12.7
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! foundation-emails-template@1.0.0 build: gulp --production
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the foundation-emails-template@1.0.0 build script 'gulp --production'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the foundation-emails-template package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp --production
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs foundation-emails-template
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls foundation-emails-template
npm ERR! There is likely additional logging output above.
 
npm ERR! Please include the following file with any support request:
 
npm ERR!     /Users/trowley/Desktop/projects/email/campaigns/eye_safety/npm-debug.log

You commented on zacbrown@me.com's post about 3 years

Can I please have an invite?

You commented on Henrique Zambonin's post about 3 years

I tried the fix several times and continue to get an error when I am attempting to launch npm run build. Is there anyone would could post their gulp file code here to ensure that I am not having an issue. I continue to get an error on the replace function. 

You commented on Henrique Zambonin's post about 3 years

 Thank you @Corey, I didn't see that in the original thread. Much appreciated!

You commented on Henrique Zambonin's post about 3 years

I am having a similar issue to this. I have tried both methods, and during the inline process it removes it. I manually added it to the inline version and it worked. Was there ever a solution found for this?

You commented on Thomas Rowley's post about 3 years

One small note, now all elements such as &nbsp; and &raquo; are converting the am-percent to &amp; instead of leaving them. Not a huge deal, just figured I would mention it. 

You commented on Thomas Rowley's post about 3 years

Hello Rafi, 
Initially, it did not work, however, after I did the update and made the change from zurb/inky to zurb/inky#develop it worked perfectly. Here is a screenshot showing it working correctly at this time. 

Thank you again for all of your help!
 
- Thomas

You commented on Thomas Rowley's post about 3 years

Rafi, 
Thank you for responding. Unfortunately, this did not fix the issue. The valign only an attribute that applies to the <td> tag, and since all of the the updated output code produces <th> to store the data, they do not work. Additionally, I looked at the output code, and valign: middle does not exist anywhere in the code. 
 

Posts Followed

Following

  • No Content

Followers

  • No Content