Let's say I've the following variables to pass to my Email Template:
$vars = array(
'products' => $products,
);
Where $products is a collection, how could I iterate over this collection in Email template?
I don't believe that Magento's templating engine is clever enough to do loops. Instead, use an inline block, as Magento does for order items. Something like this:
{{block type='core/template' area='frontend' template='path/to/your/template.phtml' products=$products}}
Hope that helps!
Thanks,
Joe
The above works, but an alternative would be to let your XML do the work by calling the layout handle in the email template:
{{layout handle="email_stuff"}}
In your local.xml or module.xml or where ever you like:
<email_stuff>
<block type="yourblock/type" name="email_stuff" template="path/to/template.phtml" />
</email_stuff>
I guess the main difference is where you're doing most of your email "work". I've used this method for loading in email headers/footers that stay the same in each template. The previous answer is likely simpler for basic tasks, however.
Related
The finishers EmailToSender and EmailToReceiver both give the format option 'html' OR 'plaintext'. How can I send emails with both, 'plaintext' AND 'html'?
The background is: AFAIK emails should always contain a defined plaintext part for those of us who are not able or do not wish to receive HTML emails. AFAIK this is required by RFC (don't know which one).
This feature was added to TYPO3v10: Send plaintext and HTML mails in EmailFinisher
As I never work much with the form-extension I don't know exactly if you're right about the mail-format, specifically that html-format never includes a text-only-part. I'd advise to check that the mail-format is really html and not multipart.
If required you can add an own finisher, also as option in the Backend selection.
In this documentation are many things described what is possible:
add own finisher class(es)
exchange data between different finishers
localize (translate) finishers
define default values
use the context of finishers
add the finisher to the UI of the backend
As first step I'd try to program a simple finisher, it can do some simple thing like adding "Hello World" to the mail or replacing the mail-text completely.
In this class I'd try to access data from other finishers and test if these data are programatically available even without activating the other finishers by choice in backend. If that's possible you could retrieve data from the two finishers for text- and html-mail and combine them according to your need.
To add a bit code here, this is how a simple finisher is included:
TYPO3:
CMS:
Form:
prototypes:
standard:
finishersDefinition:
CustomFinisher:
implementationClassName: 'VENDOR\MySitePackage\Domain\Finishers\CustomFinisher'
and this is a simple finisher-class:
declare(strict_types = 1);
namespace VENDOR\MySitePackage\Domain\Finishers;
class CustomFinisher extends \TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher
{
protected $defaultOptions = [
'yourCustomOption' => 'Olli',
];
// ...
}
Further details you have to read in the documentation or ask more detailed.
I created a model in SugarCRM and I need to print the details view. But this must be printed with a different layout.
It must have the company logo for example, if I just wanted do print the bean information, the default print would be sufficient, but I need something closer to a report, because this info will be given to the costumer.
I would like to know if there is a way to create a printing template, and if there is, how can I create one?
Thanks for your help, if you need more information please comment.
rfnpinto
Even in SugarCRM CE you can leverage the included Sugarpdf class, which is an extension of TCPDF.
If you have SugarCRM Professional you can find examples of this in the Quotes module. If not, you're flying blind, so I can give you the gist of it.
Using the Contacts module as an example, create /custom/modules/Contacts/views/view.sugarpdf.php with contents like the following:
<?php
require_once('include/MVC/View/views/view.sugarpdf.php');
/**
* this defines the view that will drive which PDF Template we use
*/
class CustomContactsViewSugarpdf extends ViewSugarpdf{
public function display(){
$this->sugarpdfBean->process();
$this->sugarpdfBean->Output($this->sugarpdfBean->fileName,'D');
sugar_die('');
}
}
Create /custom/modules/Contacts/sugarpdf/sugarpdf.pdfout.php with contents like the following:
$contact = BeanFactory::getBean($_REQUEST['record_id']);
if(empty($contact->id)){
sugar_die('Could not load contact record');
}
$name_str = "<p><strong>Name: {$contact->name}</strong></p>";
$this->writeHTML($name_str);
$this->drawLine();
}
function buildFileName(){
$this->fileName = 'ContactPDFOut.pdf';
}
}
From there, you can print a PDF document per your format if you hit the URI index.php?module=Contacts&action=sugarpdf&sugarpdf=pdfout&record_id=1234
Once that's working in the way you want, you can add a button the Contacts Detailview to access that URI more easily. Dig into /custom/modules/Contacts/metadata/detailviewdefs.php and find the existing buttons array. It'll look something like this:
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES'
Just enhance this with your own button and hidden input
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES',array(
'sugar_html'=>array(
'type' => 'submit',
'value' => '(Wrongfully Hardcoded Label) Print PDf',
'htmlOptions'=>array(onclick => 'this.form.action.value=\'sugarpdf\';this.form.sugarpdf.value=\'pdfout\'')
)
)
...
The hidden array should be part of $viewdefs['Meetings']['DetailView']['templateMeta']['form'] and defined like so:
'hidden' => array('<input type="hidden" name="sugarpdf">'),
I haven't tested this recently but this is the general idea of adding custom Print PDF abilities to any particular screen within SugarCRM. TCPDF options are pretty extensive and forming the template just right is going to be very tedious, but I think once the "plumbing" is working here you'll figure that bit out, but feel free to ask followup questions.
app\locale\en_US\template\email\sales\order_new.html is the file in question.
How would one go about editing {{var payment_html}} without affecting other sections of the site?
It seems like the section comes from: app\design\frontend\base\default\template\payment\info\default.phtml
Am I correct about this? But that file is used in other places on the site. Is that correct too?
I want to create a separate file, say default_email.phtml, style it separately, and have order_new.phtml include the new file instead.
I assume that I need to include my default_email.phtml file in layout\***.xml. Where would I do this?
The first thing I did was a search in the source code of Magento. Assuming the {{var payment_html}} is processed somewhere I searched on payment_html.
Several results are matching the search;
Mage_Sales_Model_Order
Mage_Sales_Model_Order_Creditmemo
Mage_Sales_Model_Order_Invoice
Mage_Sales_Model_Order_Shipment
So the information for that payment block has to be in there. I took Mage_Sales_Model_Order and checked the variable $paymentBlockHtml. This is pointed to further logic to fill the payment block by payment information. It's creating a block and it looks like this is not easy to extend/change/modify on the first look.
Yes, we can apply a template to the specific (payment) block type since there’s a block created, but we can’t easily check which block we want to load. Also the template is overruled in the construct of Mage_Payment_Block_Info
Let’s check the other way.
Let’s do something cool, why we don’t add a block to the email which contains the correct information but more important where it’s possible to make a switch to the correct case. Since template parser is used for parsing the variables and layout handles we could add the following on instead of the {{var payment_html}} block and retrieving that information in the block itself.
{{block type='core/template' template='email/templatename.phtml'}}
The above code is parsing the email/templatename.phtml into the email, which means that you could do anything in that template to show the correct data.
Before we can retrieve the payment data in this template we have to add the order argument with the order data. That’s quite simple;
{{block type='core/template' order=$order template='email/templatename.phtml'}}
In the template we can do $this->getOrder()->getPayment() to retrieve the payment information, or $this->getOrder->getPayment()->toHtml() or process the data in another way.
Bonus;
Another solution is working with layout handles and set the correct template and type in the layout.xml, below an example for the order items in the same email. It’s working the same as the block, but only with some settings in the layout xml.
{{layout handle="sales_email_order_items" order=$order}}
In /app/code/core/Mage/Sales/Model/Order.php there is a method called "sendNewOrderEmail". This is what you need to affect. You will find code simmilar to the following:
$mailTemplate->setDesignConfig(array('area'=>'frontend', 'store'=>$this->getStoreId()))
->sendTransactional(
$template,
Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $this->getStoreId()),
$recipient['email'],
$recipient['name'],
array(
'order' => $this,
'billing' => $this->getBillingAddress(),
'payment_html' => $paymentBlock->toHtml(), //Just change this line
)
);
You can see that this is where the "payment_html" data gets set. Just swap it out to what you want it to be.
I had the same issue. What I did to only change the email was add the following to the payment info class.
protected function _construct() {
parent::_construct();
$this->setTemplate('payment/info/{new template}.phtml');
}
Then create the template and the email will insert this template to the payment section if this payment method is used.
Hope that's helpful!
I've created custom form using FAPI for my site. And I place each control at specific location base on template provided by the designer. For instance -
<div id="myform">
<span>Enter Your Name : </span> <?php print drupal_render($form['name']); ?>
<span>Gender : </span><?php print drupal_render($form['gender_radio']); ?>
....
</div>
<?php print drupal_render($form['submit']); ?>
Here's my question - How do I enclose all the elements inside form tag? Is hardcoding the form tag inside the template file right way to do in drupal? or is it better to create in hook_form? But doing so would require me to add closing form tag at the end manually. Any suggestion would be highly appreciated.
Drupal - 6.x
It sounds like maybe you read about building individual fields, but skipped over some basic concepts of FAPI. In short, if you call the form with drupal_get_form(), you get the form container (and many of the benefits of using FAPI, e.g. tokens, validation, etc.) automatically. To handle the markup that goes around your form elements, you can then use #prefix, #suffix, and markup elements.
You can assemble the whole form from the outside in like you're doing, but there are few cases in which that would really be worthwhile. If you really want to do that, you basically want to copy what drupal_get_form() does to get the form wrapper added in a way that will work with FAPI.
I have create a new content type and added new form items using CCK. I need to customise the layout of the form which I've partially managed using css and moving items around and adding custom markup in the form_alter hook. However, this still isn't enough as the weightings don't appear to be doing exactly what I want them to do.
Is there a way I can do this using a theme.tpl.php file?
Thanks
Steve
once in a time I was in the same situation and found a quite easy solution.
I needed a highly customized registration form and form_alter was a mess. So I used a template for the form and printed each field into the html output.
First register a new template for the form in template.php of you theme.
<?php
function your-theme-name_theme() {
return array(
'user_register' => array(
'arguments' => array('form' => NULL),
'template' => 'user-register',
),
);
}
?>
Now add a new template to your theme. In my case "user_register.tpl.php". Add the following lines to it, so that the form still works.
<?php
print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']);
print drupal_render($form['form_token']);
?>
From there on you can add as much html as you want and put the form fields where ever you need them. Here are examples for the gender and birthday field. As you can see you have to use the internal CCK names.
<?php print drupal_render($form['field_profile_gender']); ?>
<?php print drupal_render($form['field_profile_birthday']); ?>
I have not tested this for any other form than user_register, but I guess it should work as long as the template name equals the name of the form.
I hope this will help you.
Regards
Mike