나는 grails 프로젝트에서 이메일 뷰를 정리하려고한다. 우리 팀은 모든 이메일에 대해 동일한 소개, 로고 및 사인을 사용합니다. 나는 이것을 전통적인 grails 레이아웃 파일에 넣으려고하고 <meta name="layout" content="email"/>
메타 태그로 호출하려고 시도했지만 작동하지 않는 것 같습니다. 이 이메일 템플릿을위한 단 하나의 레이아웃을 만들 수있는 또 다른 방법이 있습니까?Grails 이메일의 DRY 레이아웃?
답변
DRY로 무엇을 의미하는지 알아 내려고했는데, 루비 용어 라야한다고 생각합니다. 템플릿이라고 생각합니다.
HTML 전자 메일의 문제점은 실제로 로고 (머리글/바닥 글)를 포함 할 때 모든 언어의 표준 문제입니다. 표준이 다양하고 일부 메일 클라이언트에서 작동하는 동안 예를 들어 웹 메일 (예 : Gmail)에서 작동하지 않을 수 있습니다.
트릭 내가 당신에게에서 작업하는 몇 가지 예제 물건을 줄 것이다 인라인 이미지를 사용하는 것입니다 : 그래서 여기
은 샘플 컨트롤러 - 이것은 내 자신의 코드 끌 수 있으나 다른 부분에서입니다. 그것은 당신에게 아이디어를 제공하는 것입니다 아니면 내가 아주 잘 멀티 인라인 이미지 주위를 구체적으로 설명하지 말해야한다 :
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 콘텐츠 형식과 실제 파일 이름을 containts 경우 나는 목록을 가지고 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는 템플릿을 사용하여 같이 일할 것이라고 생각 비트는 대신 원하는 것을하지 않습니다 당신이 할 수있는 상기와 그것이 템플릿을 렌더링하고있는 것을 보아라. 그러나 템플릿은 html 페이지에 가득 차있는 전형적인 gsp 템플릿이다 :
당신은 HTML 이메일로 주요 문제는 CSS 스타일이 매우 잘 작동하지 않는다는 것입니다 볼<%@ 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>
, 그것은 어떤 경우에는 그러나 많은 경우에 작동
/이메일/emailTemplate를 사용하면 더 나은 기존 테이블을 고수하고 스타일 태그를 사용하여 레이아웃을 올바르게 선언합니다.
이 과정이 진행되는 동안 실제 사이트 CSS 파일을 사용하는 것을 잊어 버리십시오. 직접 이메일을 생성하여 전송하기 때문입니다. 사이트 CSS 파일에 대한 인식이 없습니다. 여러 이미지에 관해서
우리는 여기에 대해
사용자의 목록입니다 이야기USERA {USERA 사진}/사용자 A 설명 사용자 B {사용자 B 사진}/사용자 B의 설명 위의
솔루션에는 필요한 모든 인라인 이미지를 추가하는 데 필요한 모든 것이 있습니다. 즉 이메일에 이미지를 첨부하고 있다는 의미이므로 이미지가 거대하면 이미지를 다시 포맷하고 크기를 조정하기 위해 이미지를 첨부합니다.
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 [:]
}
: 당신의 자신의 위치에 대한
당신이 뭔가를 시도 할 수-크기 다시 비행에 직접 그렇게 실제 크기가 이메일로 전송을 포함하는 별도의 파일/폴더가 있지만위한 수 있습니다 로고를 이것은 지금은 위의 이미지 매핑을 수행 할 때까지 매핑이 내가 필요한 모든가 크기를 조정할만큼의 이미지와 함께 HTML 이메일을 달성하기 위해 통과했다 두통을 많이 웁니다
def res = PhotosBean.getPhoto(ui.attributes.profilePhoto)
if (res) {
images << [id: "uImage${ui.id}", contentType: "${res.contentType}", file: res.file]
}
희망 내가 원하는 번호 :
DRY는 "Do not Repeat Yourself"의 약자로, 두 곳에서 동일한 코드를 사용하지 않으려는 깨끗한 코드 교리입니다. – billjamesdev
https://github.com/vahidhedayati/grails-bean-validation-examples에는 위의 코드가 모두 포함 된 매우 복잡한 이미지 bean이 포함되어 있습니다. https://www.youtube.com/watch?v=ATLQ7CCvPvI 여기에 설명되어 있으며 귀하가 습득하려고 시도한 내용을 다루고 있습니다. Whist this with this example 프로젝트의 일부로 포함 된 복잡한 이미징 메커니즘이 있다는 것을 깨달았다. https://github.com/vahidhedayati/grails-bean-validation-examples/tree/master/src/main/groovy/ org/imgscalr – Vahid
- 1. Grails 프로젝트 간 코드 재사용 - 유지 DRY
- 2. expressjs 렌더링에서 레이아웃 로컬을 DRY up
- 3. - DRY
- 4. 주석을 사용하여 Groovy/Grails 코드가 DRY 상태를 유지할 수 있습니까?
- 5. DRY Rails 마스터 템플릿?
- 6. Android - DRY 원칙에 따라 여러 레이아웃 파일을 어떻게 관리합니까?
- 7. 트위터 부트 스트랩이있는 Grails 페이지 레이아웃
- 8. Grails 레이아웃, 어떻게 할 수 있습니까?
- 9. 모바일 사용자를위한 다른 grails 레이아웃 선택
- 10. Grails : 레이아웃 GSP에서 뷰 이름 가져 오기
- 11. DRY 방법
- 12. DRY 사용
- 13. DRY 루트
- 14. 설정 DRY
- 15. 이메일의 문자 집합을 결정합니다.
- 16. 이메일의 Regexp (쿼리)가 @
- 17. 이메일의 페이지 수
- 18. 이메일의 멋진 출력 형식
- 19. 이메일의 원래 수신자 찾기
- 20. 복잡한 이메일의 정규식
- 21. 이메일의 링크를 인식
- 22. 이메일의 헤더가 작동하지 않습니다.
- 23. Mailchimp 이메일의 인코딩 문제
- 24. 이메일의 텍스트 마이닝
- 25. 이메일의 변수 제목
- 26. 이메일의 스타일 테이블
- 27. 이메일의 동적 이미지
- 28. 이메일의 확인 코드
- 29. AppleScript로 이메일의 날짜 받기
- 30. 이메일의 모양 - 좋은 습관?
이것은 작동하지 않습니다. 이메일 템플리트 내에서 이미지 ID 태그와 일치하는 인라인 이미지 첨부 파일을 조사해야합니다. 여러 이미지 = 여러 개의 인라인 첨부 파일 – Vahid