DRY Layouts for Grails电子邮件? [英] DRY Layouts For Grails Emails?

查看:140
本文介绍了DRY Layouts for Grails电子邮件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在清理我的Grails项目中的一些电子邮件视图。我的团队对每封电子邮件使用相同的介绍,标识和签名。我试图将它们放入传统的格式布局文件中,并使用元标记< meta name =layoutcontent =email/> 似乎没有工作。还有另一种方式可以为这些电子邮件模板创建一个单一的布局?

I'm trying to clean up some of the the email views in my grails project. My team uses the same introduction, logo, and sign off for every email. I tried to place these into the traditional grails layout file and call it with the meta tag <meta name="layout" content="email"/>, but it doesn't appear to work. Is there another way I can create one singular layout for these email templates?

推荐答案

我试图弄清楚你的意思干,我认为这必须是一些红宝石术语,我猜你的意思是模板。

I was trying to figure out what you mean by DRY, I think it must be some ruby term and I guess you mean templates.

HTML电子邮件的问题实际上是跨所有语言的标准问题,就像包含标志(页眉/页脚)一样。标准不同,虽然它可能在某些邮件客户端上可能无法工作,例如网络邮件,即Gmail等。

The problem with HTML emails is actually a standard problem acrosss all languages as in when it comes to including logos (headers/footers). The standards vary and whilst it may work on some mail clients may not work on for example web mail i.e. gmail and so forth.

诀窍是使用内联图像我将给你一些示例的东西从以下工作:

The trick is to use inline images I will give you some sample stuff to work from:

所以这里是一个示例控制器 - 这是我自己的代码,但不同的部分。这是给你一个想法,或者我应该说不是很好地解释了多个内联图像:

So here is a sample Controller - this is off my own code but from different parts. It is to give you an idea or should I say not very well explained specifically around multi inline images:

class Mycontroller() { 
   pivate final static String TEMPLATE='/emails/emailTemplate'
   def emailService
   def doEmail() { 
    def images=[]
    //Where this list contains a map of photo Ids(could be macde up, the photo content type and actual photo file Names (to go and grab from uploaded folder)
    images <<[id: "uImage${photo.id}", contentType: "${photo.contentType}", file: photo.file]
    images <<[id: "uImage${photo1.id}", contentType: "${photo1.contentType}", file: photo1.file]
    emailService.sendEmail(user.email, subject, TEMPLATE, [instance: bean, domainName:domainName, fqdn:fqdn ], images)
  }
}

如果上面的图像包含照片ID,内容类型和实际文件名(在文本)发送到emailService.se ndEmail

I have a list if images above it containts the photo id the content type and the actual file name (in text) that is sent through to emailService.sendEmail

private void sendEmail(email,mysubject,template,templateModel,List images) throws Exception {
        List<String> recipients = []       
        try {
            mailService.sendMail {
                //this must be set true and at the top for inline images to work
                multipart true
                if (recipients) {
                    to recipients
                }
                else {
                    to email
                }
                if (config.admin.emailFrom) {
                    if (Environment.current == Environment.DEVELOPMENT && config.admin.emailFromDev ) {
                        from "${config.admin.emailFromDev}"
                    } else {
                        from "${config.admin.emailFrom}"
                    }
                }
                subject mysubject
                //actual content must be html sent to fill in a grails template
                html Holders.grailsApplication.mainContext.groovyPageRenderer.render(template: template, model: templateModel)
                //Main Site logo
                inline 'inlineImage', 'image/png', new File("/opt/site-stuff/myLogo.png")
                //Additional images 
                if (images) {
                    images?.each { a ->
                        inline "${a.id}", "${a.contentType}", new File("${a.file}")
                    }
                }
            }
        }
        catch (e) {
            //throw new Exception(e.message)
            log.error "Problem sending email ${e.message}"
        }
    }

现在有一点你以为会像使用Grails模板一样工作你在布局中的方式不是你想要的,如上所述,你可以看到它是渲染一个模板,但是模板是一个典型的gsp模板,而是在html页面上是一个完整的:

Now the bit that you thought would just work as in using grails templates in the way you are as in layouts is not what you want instead, as above you can see it is rendering a template but the template is a typical gsp template which instead is a full on html page:

/ emails / emailTemplate

/emails/emailTemplate

<%@ page contentType="text/html;charset=UTF-8" %>
<!doctype html>
<html>
<head>
<style>
    .site-icon img {
        width: 300px;
        margin-top:-50px;
    }
    .site-logo img {
        min-width: 25em;
        max-width: 45em;
    }
    .menu {
        background: #CCC;
    }
    a {
        text-decoration: none;
    }
    .menu a {
        color : #FF0000;
        text-decoration: none;
        font-weight:bold;
    }
    .menu a:hover {
        color : #00FFFF;
        background: #ccc;
    }    
</style>
</head>
<body style=" background-color: blue; font-size: 1.0em;">
<table  width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
    <tr style="background: red;"><td colspan="3" class="site-logo">
        <img src="cid:inlineImage"/>
        <h1 style="display:inline; margin-top:-2em;"><g:message code="domain.label"/></h1>
    </td>
    </tr>

      <g:each in="${instance.results}" var="user" status="ii">
      <tr><td>
       <div class="image">
                    <g:if test="${user.profilePhoto}">
                        <img src="cid:uImage${user.id}"/>
                    </g:if>
                </div>

           </td></tr>

      </g:each>
</table>

你看到html电子邮件的主要问题是CSS样式不能很好地工作,它的工作原理在某些情况下,但在很多情况下,您最好坚持使用传统表格,并使用样式标签来正确声明布局。

You see the main problem with html emails is that CSS styles don't work very well, it works in some cases but in a lot of cases you are better off sticking to traditional tables and using style tags to properly declare your layout.

忘记使用您的实际网站CSS文件,因为这个过程,这是一个直接的电子邮件被生成和发送。它没有您的网站CSS文件的意识。

Forget about using your actual site CSS files since so far as this process goes, this is a direct email being generated and sent. It has no awareness of your site CSS files.

关于多个图像,我们在谈论

In regards to multiple images we are talking about

是用户列表

usera {usera Photo} / userA描述
userb {userb Photo} / userB描述

usera {usera Photo} / userA Description userb {userb Photo} / userB Description

上述解决方案将拥有所有您需要添加所需的所有内嵌图像。这意味着你附加的电子邮件中的图像,如果图像是巨大的,那么你也附加它们,所以诀窍是重新格式化图像/调整大小。

The above solution will have all you need to add all the inline images you need to do this. This means you are attaching the images within the email so if the images are huge then you are also attaching them so the trick is to reformat the images / resize them.

对于您自己的网站标志,您可以直接执行此操作,并具有一个单独的文件/文件夹,其中包含要发送电子邮件的实际大小,但是您可以尝试重新调整大小如下所示:

For your own site logos you can do that directly and have a separate file/folder that contains actual size to be emailed but for on the fly re-sizing you could try something like this:

   static Map getPhoto(Photos photo, int width=100,int height=100) {
        File f
        def contentType
        if (photo.status==Photos.ACTIVE) {
            def id = photo.id
            def imageSHa = photo.imageSHa
            contentType = photo.contentType
            def fileExtension = photo.fileExtension
            //remove . from fileExtension
            def noDotExtension = fileExtension.substring(1)
            def user = photo.user
            f = new File(ROOT_PATH + '/' + user.username + '/' + imageSHa);
            if (f.exists() && !f.isDirectory()) {
                f = new File(ROOT_PATH + '/' + user.username + '/' + imageSHa+'_email');
                if (!f.exists()) {
                    def imageStream = new FileInputStream(ROOT_PATH + '/' + user.username + '/' + imageSHa)
                    def image = FileCopyUtils.copyToByteArray(imageStream).encodeBase64().toString()
                    def caption = photo.caption
                    def position = photo.position
                    // String caption=photo.caption
                    //Lets present the image as a thumbNail
                    imageStream = new FileInputStream(ROOT_PATH + '/' + user.username + '/' + imageSHa)
                    def imageBuffer = ImageIO.read(imageStream)
                    def scaledImg = Scalr.resize(imageBuffer, Scalr.Method.QUALITY, width, height, Scalr.OP_ANTIALIAS)
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ImageIO.write(scaledImg, noDotExtension, os)
                    InputStream is = new ByteArrayInputStream(os.toByteArray())

                    def scaledImage = FileCopyUtils.copyToByteArray(is).encodeBase64().toString()
                    //imageSHa = DigestUtils.shaHex(scaledImg)
                    byte[] data = Base64.decodeBase64(scaledImage)
                    OutputStream stream = new FileOutputStream(ROOT_PATH + '/' + user.username + '/' + imageSHa+'_email')
                    stream.write(data)
                    f = new File(ROOT_PATH + '/' + user.username + '/' + imageSHa+'_email');
                }
                return [file:f, contentType:'img/'+fileExtension.substring(1)]
            }

        }
        return [:]
    }

现在映射到我上面做图像映射时: / p>

This now maps up to when I was doing the images mapping above:

 def res = PhotosBean.getPhoto(ui.attributes.profilePhoto)
                            if (res) {
                                images << [id: "uImage${ui.id}", contentType: "${res.contentType}", file: res.file]
                            }

希望这清除了很多头痛,我不得不通过尽可能多的图像实现html电子邮件,并且都调整到我想要的

Hope this clears up a lot of headache I had to go through to achieve html emails with as many images as required and all resized to what I want

这篇关于DRY Layouts for Grails电子邮件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆