Expand my Community achievements bar.

SOLVED

Send email via FORM in CQ5

Avatar

Level 4

Hi,

I'm trying to send e-mail with some information provided via <form> but I'm not really sure how to do it. I've understood that I need to create Servlet that process the form data and sends the email. I've tried to follow these instructions but it's not clear enough for CQ5/Servlet(I don't have any experience with Servlets) newbie like me. I've successfully created the component(I already have some experiences with components) and bundle under /apps/myapp/src but I don't know what to do next and where to put all the code. I'm getting confused in the "Creating the HTML Email Servlet" part. Where should I put that code there? Into my component or into the Servlet? I think I should put this
 

String template = properties.get("emailTemplate","/notset"); Resource templateRsrc = request.getResourceResolver().getResource(template); if (templateRsrc.getChild("file") != null) { templateRsrc = templateRsrc.getChild("file"); } if (templateRsrc == null) { throw new IllegalArgumentException("Missing template: " + template); } final MailTemplate mailTemplate = MailTemplate.create(templateRsrc.getPath(), templateRsrc.getResourceResolver().adaptTo(Session.class)); final HtmlEmail email = mailTemplate.getEmail(StrLookup.mapLookup(properties), HtmlEmail.class);

to the component code but how do I pass all the info to the servlet after the user submits the form?

So basically I need to get data from html form(created with my component) and then send it to some e-mail. Can you help me? Some commented working code will be enough, I can program in Java so I can edit it to my needs.
BTW I the mailing settings in OSGi are already properly set.

Thanks for any help and sorry for my poor english and poor description of the problem.

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

A servlet is just a Java class that implements a specific interface, making it able to process HTTP requests. Those HTTP requests are usually made by an HTML form submission, but nothing about that is required. The servlet must be registered to a specific set of criteria (a path location, resource type, etc.) so that Sling knows when to invoke the servlet as the processing mechanism for an HTTP request. High level, here's what you'll need to do:

  1. Create a class, in your bundle, that extends SlingAllMethodsServlet. This will be the code that "receives" your form data and does something with it.
  2. In that servlet, override the doPost method. Your form should be making a POST request and by implementing the doPost method, the servlet will be able to react to the POST request made by the client via the form submission. All of your processing logic (i.e. sending the email) should be inside the doPost method.
  3. Register your servlet class to an appropriate selector, and resource type in the repository. This is how you associate your servlet class with a specific path. By registering to a resource type and selector, you are saying "whenever a form makes a post to a request path that includes x selector and the resource at that path is of resource type y use THIS servlet to process the request." I typically use the selector "form" for all POST requests that are from a form, but anything reasonable will do. I would register your servlet to the resource type that corresponds with your "email form" component. You can reference this page about Sling Servlets for more detail and other options for registering them.
  4. You need to decide what the response to this form request is going to be. I'm assuming after the submission, you'll forward the user to some "thank you" page. If so, you'll also want to register the servlet to the extension "html" and make sure your doPost method redirects the user to an HTML page after processing the email stuff.
  5. Make sure your HTML form has the method "POST" and the action equal to the path of the "current component." That means it will effectively post to itself, which is where I recommended you register the Sling Servlet. That URL will look something like /content/myapp/page/par/emailformcomponent/jcr:content.form.html. The ".html" should correspond to the extension in step 4, so if you decided the response will be JSON or something else, a different extension would be appropriate. Remember the jcr:content node of a component is actually the resource that has the resource type.

Hope this helps.

View solution in original post

2 Replies

Avatar

Correct answer by
Former Community Member

A servlet is just a Java class that implements a specific interface, making it able to process HTTP requests. Those HTTP requests are usually made by an HTML form submission, but nothing about that is required. The servlet must be registered to a specific set of criteria (a path location, resource type, etc.) so that Sling knows when to invoke the servlet as the processing mechanism for an HTTP request. High level, here's what you'll need to do:

  1. Create a class, in your bundle, that extends SlingAllMethodsServlet. This will be the code that "receives" your form data and does something with it.
  2. In that servlet, override the doPost method. Your form should be making a POST request and by implementing the doPost method, the servlet will be able to react to the POST request made by the client via the form submission. All of your processing logic (i.e. sending the email) should be inside the doPost method.
  3. Register your servlet class to an appropriate selector, and resource type in the repository. This is how you associate your servlet class with a specific path. By registering to a resource type and selector, you are saying "whenever a form makes a post to a request path that includes x selector and the resource at that path is of resource type y use THIS servlet to process the request." I typically use the selector "form" for all POST requests that are from a form, but anything reasonable will do. I would register your servlet to the resource type that corresponds with your "email form" component. You can reference this page about Sling Servlets for more detail and other options for registering them.
  4. You need to decide what the response to this form request is going to be. I'm assuming after the submission, you'll forward the user to some "thank you" page. If so, you'll also want to register the servlet to the extension "html" and make sure your doPost method redirects the user to an HTML page after processing the email stuff.
  5. Make sure your HTML form has the method "POST" and the action equal to the path of the "current component." That means it will effectively post to itself, which is where I recommended you register the Sling Servlet. That URL will look something like /content/myapp/page/par/emailformcomponent/jcr:content.form.html. The ".html" should correspond to the extension in step 4, so if you decided the response will be JSON or something else, a different extension would be appropriate. Remember the jcr:content node of a component is actually the resource that has the resource type.

Hope this helps.

Avatar

Level 10

You can create your own code to perform this entire workflow. TO see how to write a Sling servlet -- see:

1. http://scottsdigitalcommunity.blogspot.ca/2013/06/posting-form-data-to-adobe-cq-using.html -- this article will teach you how to create a Sling Servlet in CQ. Now instead of encoding the passed in form data to JSON data (as shown in this article)  -- create an email service and email the data passed to the Sling Servlet. 

2 - THis article discusses how to create a custom email service within CQ: http://scottsdigitalcommunity.blogspot.ca/2012/07/creating-custom-cq-email-services.html. This article passed data  form the form to CQ by invoking an OSGi from a JSP page and passing in the data. 

So you can combine the articles -- post form data to a Sling Servlet and then call the Email service. Or just follow article 2 and simply invoke the OSGi operation from a JSP. 

 

Hope this helps.

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----