{"__v":0,"_id":"550979ba4c7c3f2300aabf03","category":{"__v":16,"_id":"550974cc368a56170041475b","project":"55070e814bb83b2500ec9404","version":"550974cb368a561700414757","pages":["55097808ad1f0523008ecbca","550979624c7c3f2300aabf01","5509797daa9bd525001a0656","550979a0aa9bd525001a0658","550979ba4c7c3f2300aabf03","550979e6dd77250d007369f2","55097a02dd77250d007369f4","55097a0fad1f0523008ecbce","55097a1baa9bd525001a065a","55097a212dd6a11900e6e7b0","55097a28ad1f0523008ecbd0","55097a304c7c3f2300aabf05","55097a3add77250d007369f6","55097a402dd6a11900e6e7b2","55097a6fdd77250d007369f8","55097a77ad1f0523008ecbd2"],"reference":false,"createdAt":"2015-03-18T11:08:22.079Z","from_sync":false,"order":3,"slug":"handling-requests-with-controllers","title":"Handling Requests with Controllers"},"project":"55070e814bb83b2500ec9404","user":"55070d24d30b3f190011b941","version":{"__v":1,"_id":"550974cb368a561700414757","forked_from":"55070e814bb83b2500ec9407","project":"55070e814bb83b2500ec9404","createdAt":"2015-03-18T12:51:23.709Z","releaseDate":"2015-03-18T12:51:23.709Z","categories":["550974cc368a561700414758","550974cc368a561700414759","550974cc368a56170041475a","550974cc368a56170041475b","550974cc368a56170041475c","550974cc368a56170041475d","550974cc368a56170041475e"],"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.4.0","version":"1.4"},"updates":[],"createdAt":"2015-03-18T13:12:26.358Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"auth":"required","params":[],"url":""},"order":4,"body":"Sending emails in Wheels is done from your controller files with the\n[sendEmail()][1] function. It's basically a wrapper around `cfmail`, but it has\nsome smart functionality and a more Wheels-like approach in general.\n\nGetting this to work in Wheels can be broken down in 3 steps. We'll walk you\nthrough them.\n\n## Establishing Mail Server and Account Information\n\nWe recommend using Wheels ability to set global defaults for [sendEmail()][1] so\nthat you don't have to specify more arguments than necessary in your controller\nfiles. Because it's likely that you will use the same mail server across your\napplication, this makes it worthwhile to set a global default for it.\n\nThis setting should be done in the `config/settings.cfm` file and can look\nsomething like this:\n\n```cfml\n<cfset set(\n    functionName=\"sendEmail\",\n    server=\"yourServer\",\n    username=\"yourUsername\",\n    password=\"yourPassword\"\n)>\n```\n\nBy specifying these values here, these arguments can be omitted from all\n[sendEmail()][1] function calls, thus providing cleaner, less cluttered code.\n\nBut you are not limited to setting only these 3 variables. In fact, you can set\na global default for any optional argument to [sendEmail()][1] and since it\naccepts the same arguments that `cfmail` does. That's quite a few.\n\n## Create an Email Template\n\nAn email template is required for [sendEmail()][1] to work and forms the basis\nfor the mail message content. Think of an email template as the content of your\nemail.\n\nTemplates may be stored anywhere within the `/views/` folder, but we recommend a\nstructured, logical approach. If different controllers utilize [sendEmail()][1]\nand each require a unique template, place each email template within the\n`views/controllername` folder structure.\n\nConsider this example scenario:\n\n<table>\n\t<tbody>\n\t\t<tr>\n\t\t\t<th>Controller:</th>\n\t\t\t<td><code>Membership</code></td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<th>Email Template:</th>\n\t\t\t<td><code>/views/membership/myemailtemplate.cfm</code></td>\n\t\t</tr>\n\t</tbody>\n</table>\n\nMultiple templates may be stored within this directory should there be a need.\n\nThe content of the template is simple: simply output the content and any\nexpected variables.\n\nHere's an example for `myemailtemplate.cfm`, which will contain HTML content.\n\n```cfml\n<cfoutput>\n<p>Hi #recipientName#,</p>\n<p>\n    We wanted to take a moment to thank you for joining our service\n    and to confirm your start date.\n</p>\n<p>\n    Our records indicate that your membership will begin on\n    <strong>#DateFormat(startDate, \"dddd, mmmm, d, yyyy\")#</strong>.\n</p>\n</cfoutput>\n```\n\n## Sending the Email\n\nAs we've said before, [sendEmail()][1] accepts all attribute of CFML's `cfmail`\ntag as arguments. But it also accepts any variables that you need to pass to the\nemail template itself.\n\nConsider the following example:\n\n```cfml\n<cfset member = model(\"member\").findByKey(newMember.id)>\n<cfset\n    sendEmail(\n        from=\"service@yourwebsite.com\",\n        to=member.email,\n        template=\"myemailtemplate\",\n        subject=\"Thank You for Becoming a Member\",\n        recipientName=member.name,\n        startDate=member.startDate\n    )\n>\n```\n\nHere we are sending an email by including the `myemailtemplate` template and\npassing values for `recipientName` and `startDate` to it.\n\nNote that the `template` argument should be the path to the view's folder name\nand template file name without the extension. If the template is in the current\ncontroller, then you don't need to specify a folder path to the template file.\nIn that case, just be sure to store the template file in the folder with the\nrest of the views for that controller.\n\nThe logic for which template file to include follows the same logic as the\n`template` argument to [renderPage()][2].\n\nDid you notice that we did not have to specify the `type` attribute of `cfmail`?\nWheels is smart enough to figure out that you want to send as HTML since you\nhave tags in the email body. (You can override this behavior if necessary though\nby passing in the `type` argument.)\n\n### Multipart Emails\n\nThe intelligence doesn't end there though. You can have Wheels send a multipart\nemail by passing in a list of templates to the `templates` argument (notice the\nplural), and Wheels will automatically figure out which one is text and which\none is HTML.\n\nIt is also important to note that the `template` argument should be the path to\nthe view's folder name and template file name without the extension. If the\ntemplate is in the current controller, then you don't need to specify a folder\npath to the template file. In that case, just be sure to store the template file\nin the folder with the rest of the views for that controller.\n\nLike the `template` argument, the logic for which file to include follows the\nsame logic as the `template` argument to [renderPage()][2].\n\n### Attaching Files\n\nYou can attach files to your emails as well by using the `file` argument (or\n`files` argument if you want multiple attachments). Simply pass in the name of a\nfile that exists in the `files` folder (or a subfolder of it) of your\napplication.\n\n## Using Email Layouts\n\nMuch like the layouts outlined in the [Using Layouts][3] chapter, you can also\ncreate layouts for your emails.\n\nA layout should be used just as the name implies: for layout and stylistic\naspects of the email body. Based on the example given above, let's assume that\nthe same email content needs to be sent twice.\n\n - Message is sent to a new member with a stylized header and footer.\n - A copy of message is sent to an admin at your company with a generic header\n and footer.\n\nBest practice is that variables (such as `recipientName` and `startDate`, in the\nexample above) be placed as outputs in the template file.\n\nIn this case, the 2 calls to [sendEmail()][1] would be nearly identical, with\nthe exception of the layout attribute.\n\n```cfml\n<!--- Get new member --->\n<cfset member = model(\"member\").findByKey(params.key)>\n\n<!--- Customer email with customized header/footer --->\n<cfset\n    sendEmail(\n        from=\"service@yourwebsite.com\",\n        template=\"myemailtemplate\",\n        layout=\"customer\",\n        to=member.email,\n        subject=\"Thank You for Becoming a Member\",\n        recipientName=member.name,\n        startDate=member.startDate\n  )\n>\n\n<!--- Plain text message with \"admin\" layout --->\n<cfset\n    sendEmail(\n        from=\"service@yourwebsite.com\",\n        template=\"myemailtemplate\",\n        layout=\"admin\",\n        to=\"admin@domain.com\",\n        subject=\"Membership Verification: #member.name#\",\n        recipientName=member.name,\n        startDate=member.startDate\n    )\n>\n```\n\n### Multipart Email Layouts\n\nWheels also lets you set up layouts for the HTML and plain text parts in a\nmultipart email.\n\nIf we set up generic email layouts at `views/plainemaillayout.cfm` and\n`views/htmlemaillayout.cfm`, we would call [sendEmail()][1] like so:\n\n```cfml\n<!---Multipart customer email --->\n<cfset\n    sendEmail(\n        from=\"service@yourwebsite.com\",\n        templates=\"/myemailtemplateplain,/myemailtemplatehtml\",\n        layouts=\"customerPlain,customerHtml\",\n        to=member.email,\n        subject=\"Thank You for Becoming a Member\",\n        recipientName=member.name,\n        startDate=member.startDate\n    )\n>\n```\n\nFor both the `templates` and `layouts` arguments (again, notice the plurals),\nwe provide a list of view files to use. Wheels will figure out which of the\ntemplates and layouts are the HTML versions and separate out the MIME parts for\nyou automatically.\n\n## Go Send Some Emails\n\nNow you're all set to send emails the Wheels way. Just don't be a spammer,\nplease!\n\n[1]: TBD\n[2]: TBD\n[3]: ../05-Displaying-Views-to-Users/04-Layouts.md","excerpt":"Use Wheels to simplify the task of setting up automated emails in your application.","slug":"sending-email","type":"basic","title":"Sending Email"}

Sending Email

Use Wheels to simplify the task of setting up automated emails in your application.

Sending emails in Wheels is done from your controller files with the [sendEmail()][1] function. It's basically a wrapper around `cfmail`, but it has some smart functionality and a more Wheels-like approach in general. Getting this to work in Wheels can be broken down in 3 steps. We'll walk you through them. ## Establishing Mail Server and Account Information We recommend using Wheels ability to set global defaults for [sendEmail()][1] so that you don't have to specify more arguments than necessary in your controller files. Because it's likely that you will use the same mail server across your application, this makes it worthwhile to set a global default for it. This setting should be done in the `config/settings.cfm` file and can look something like this: ```cfml <cfset set( functionName="sendEmail", server="yourServer", username="yourUsername", password="yourPassword" )> ``` By specifying these values here, these arguments can be omitted from all [sendEmail()][1] function calls, thus providing cleaner, less cluttered code. But you are not limited to setting only these 3 variables. In fact, you can set a global default for any optional argument to [sendEmail()][1] and since it accepts the same arguments that `cfmail` does. That's quite a few. ## Create an Email Template An email template is required for [sendEmail()][1] to work and forms the basis for the mail message content. Think of an email template as the content of your email. Templates may be stored anywhere within the `/views/` folder, but we recommend a structured, logical approach. If different controllers utilize [sendEmail()][1] and each require a unique template, place each email template within the `views/controllername` folder structure. Consider this example scenario: <table> <tbody> <tr> <th>Controller:</th> <td><code>Membership</code></td> </tr> <tr> <th>Email Template:</th> <td><code>/views/membership/myemailtemplate.cfm</code></td> </tr> </tbody> </table> Multiple templates may be stored within this directory should there be a need. The content of the template is simple: simply output the content and any expected variables. Here's an example for `myemailtemplate.cfm`, which will contain HTML content. ```cfml <cfoutput> <p>Hi #recipientName#,</p> <p> We wanted to take a moment to thank you for joining our service and to confirm your start date. </p> <p> Our records indicate that your membership will begin on <strong>#DateFormat(startDate, "dddd, mmmm, d, yyyy")#</strong>. </p> </cfoutput> ``` ## Sending the Email As we've said before, [sendEmail()][1] accepts all attribute of CFML's `cfmail` tag as arguments. But it also accepts any variables that you need to pass to the email template itself. Consider the following example: ```cfml <cfset member = model("member").findByKey(newMember.id)> <cfset sendEmail( from="service@yourwebsite.com", to=member.email, template="myemailtemplate", subject="Thank You for Becoming a Member", recipientName=member.name, startDate=member.startDate ) > ``` Here we are sending an email by including the `myemailtemplate` template and passing values for `recipientName` and `startDate` to it. Note that the `template` argument should be the path to the view's folder name and template file name without the extension. If the template is in the current controller, then you don't need to specify a folder path to the template file. In that case, just be sure to store the template file in the folder with the rest of the views for that controller. The logic for which template file to include follows the same logic as the `template` argument to [renderPage()][2]. Did you notice that we did not have to specify the `type` attribute of `cfmail`? Wheels is smart enough to figure out that you want to send as HTML since you have tags in the email body. (You can override this behavior if necessary though by passing in the `type` argument.) ### Multipart Emails The intelligence doesn't end there though. You can have Wheels send a multipart email by passing in a list of templates to the `templates` argument (notice the plural), and Wheels will automatically figure out which one is text and which one is HTML. It is also important to note that the `template` argument should be the path to the view's folder name and template file name without the extension. If the template is in the current controller, then you don't need to specify a folder path to the template file. In that case, just be sure to store the template file in the folder with the rest of the views for that controller. Like the `template` argument, the logic for which file to include follows the same logic as the `template` argument to [renderPage()][2]. ### Attaching Files You can attach files to your emails as well by using the `file` argument (or `files` argument if you want multiple attachments). Simply pass in the name of a file that exists in the `files` folder (or a subfolder of it) of your application. ## Using Email Layouts Much like the layouts outlined in the [Using Layouts][3] chapter, you can also create layouts for your emails. A layout should be used just as the name implies: for layout and stylistic aspects of the email body. Based on the example given above, let's assume that the same email content needs to be sent twice. - Message is sent to a new member with a stylized header and footer. - A copy of message is sent to an admin at your company with a generic header and footer. Best practice is that variables (such as `recipientName` and `startDate`, in the example above) be placed as outputs in the template file. In this case, the 2 calls to [sendEmail()][1] would be nearly identical, with the exception of the layout attribute. ```cfml <!--- Get new member ---> <cfset member = model("member").findByKey(params.key)> <!--- Customer email with customized header/footer ---> <cfset sendEmail( from="service@yourwebsite.com", template="myemailtemplate", layout="customer", to=member.email, subject="Thank You for Becoming a Member", recipientName=member.name, startDate=member.startDate ) > <!--- Plain text message with "admin" layout ---> <cfset sendEmail( from="service@yourwebsite.com", template="myemailtemplate", layout="admin", to="admin@domain.com", subject="Membership Verification: #member.name#", recipientName=member.name, startDate=member.startDate ) > ``` ### Multipart Email Layouts Wheels also lets you set up layouts for the HTML and plain text parts in a multipart email. If we set up generic email layouts at `views/plainemaillayout.cfm` and `views/htmlemaillayout.cfm`, we would call [sendEmail()][1] like so: ```cfml <!---Multipart customer email ---> <cfset sendEmail( from="service@yourwebsite.com", templates="/myemailtemplateplain,/myemailtemplatehtml", layouts="customerPlain,customerHtml", to=member.email, subject="Thank You for Becoming a Member", recipientName=member.name, startDate=member.startDate ) > ``` For both the `templates` and `layouts` arguments (again, notice the plurals), we provide a list of view files to use. Wheels will figure out which of the templates and layouts are the HTML versions and separate out the MIME parts for you automatically. ## Go Send Some Emails Now you're all set to send emails the Wheels way. Just don't be a spammer, please! [1]: TBD [2]: TBD [3]: ../05-Displaying-Views-to-Users/04-Layouts.md