Laravel 4 email template styling - css

I'm trying to give a style to my email template using bootstrap but every time what laravel is doing is, it parses the template and adds a '3D' where ever there is '=' in the template, which results in style=3D"table" instead of style="table", here is a snippet of the mail source code
<div class=3D"well">
<table class=3D"table table-bordered table-striped" id=3D'table'>
<thead>
<th>Group Name</th>
<th>Kpi Name</th>
<th>User Name</th>
</thead>
<tbody>
</tbody>
</table>
</div>
here is my code for template
<html lang="en-US">
<head>
<meta charset="utf-8">
{{ HTML::style('app\\client\\css\\bootstrap.css') }}
{{ HTML::script('app\\javascripts\\js\\jquery-1.8.3.min.js') }}
{{ HTML::script('app\\client\\js\\bootstrap.min.js') }}
<style>
#table {
border: 2px solid #ccc;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="well">
<table class="table table-bordered table-striped" id='table'>
<thead>
<th>Group Name</th>
<th>Kpi Name</th>
<th>User Name</th>
</thead>
<tbody>
#foreach ($groups as $group)
<tr>
<td>{{ $group['name'] }}</td>
<td>
<ul>
#if (array_key_exists('kpis', $group))
#foreach ($group['kpis'] as $kpi)
<li>{{ Kpi::find($kpi['kpi'])->title }}</li>
#endforeach
#endif
</ul>
</td>
<td>
<ul>
#if (array_key_exists('users', $group))
#foreach ($group['users'] as $user)
<li>{{ User::find($user['user'])->fName.' '.User::find($user['user'])->lName }}</li>
#endforeach
#endif
</ul>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
<footer>
<br>
<br>
Regards,<br>
<strong>Yogesh Joshi</strong><br>
Group Leader
</footer>
</body>
</html>
is there something I'm missing or there is some problem in laravel or mail-server (gmail or hotmail), and yeah I've cross checked the script and style files, they do exists in public folder.
please help or provide any alternate method for it.

For the =3D items, see this post: What's a 3D doing in this HTML?
And I see that you are trying to load javascript in your email, that's not a good idea. see: Is JavaScript supported in an email message?
And I am not sure about loading a stylesheet into a html email, so I will leave that one open.

Using Bootstrap in emails sounds a little bit overkill, but there's old project called Bootstrap Template for HTML Email. Not sure if this helps.
Also this question seems to be partially about the same subject as SO question "Has anyone gotten HTML emails working with Twitter Bootstrap?"
Probably easier to use HTML Email Boilerplate with just copied mini style sheet from your actual project.
Or if you're lazy, use the Mailchimp wysiwyg -editor and export it out of MC. They have really nice wysiwyg-editor and responsive templates. I've been using it and it saves some time and effort.

Related

Add CSS styles to the three first rows of a table

Given the following HTML, I want to add some CSS styles ONLY to the first .gold, .silver and .bronze rows, (having in mind some special behaviors I have commented in the code).
<table>
<tbody>
<!--
IMPORTANT:
Notice that here can appear an extra <tr class="my-rank"></tr>
(i.e.: if he user is logged in and he/she have a rank)
-->
<tr class="gold"></tr>
<tr class="silver"></tr>
<tr class="bronze"></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<!--
From this point, these <tr> elements are injected with AJAX (by a pager),
and the three first of ones, includes .gold, .silver and .bronze classes again.
I can't remove these "repeated" classes.
-->
<tr class="gold"></tr>
<tr class="silver"></tr>
<tr class="bronze"></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<tr></tr>
<!--
Here is another AJAX injection block, including again undesired .gold, .silver and .bronze classes...
-->
<tr class="gold"></tr>
<tr class="silver"></tr>
<tr class="bronze"></tr>
<tr></tr>
...
...
</tbody>
</table>
I tried several times with pseudo-selectors like ':first-of-type', :first-child, etc; (also combined with :not), with no luck.
Can someone point me to the right direction?
Just after posting this question, I found a solution (although it might not be the more elegant of the solutions):
Finally, I went with these CSS selectors:
tr.gold:nth-child(1),
tr.gold:nth-child(2) {
/* my custom styles */
}
tr.silver:nth-child(2),
tr.silver:nth-child(3) {
/* my custom styles */
}
tr.bronze:nth-child(3),
tr.bronze:nth-child(4) {
/* my custom styles */
}

How should i use if else and for loop with .hbs file (Handlebars.js)?

I know how can i use if else statement or for loop using .ejs file but i need to change code in .hbs file and i am new with this.Please help me with below example in which i have used .ejs file i need to convert it in .hbs file but don't know how to change if else and for loop
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fetch using MySQL and Node.js</title>
</head>
<body>
<div class="table-data">
<h2>Display Data using Node.js & MySQL</h2>
<table border="1">
<tr>
<th>S.N</th>
<th>Full Name</th>
<th>Email Address</th>
<th>City</th>
<th>Country</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<%
if(userData.length!=0){
var i=1;
userData.forEach(function(data){
%>
<tr>
<td><%=i; %></td>
<td><%=data.fullName %></td>
<td><%=data.emailAddress %></td>
<td><%=data.city %></td>
<td><%=data.country %></td>
<td>Edit</td>
<td>Delete</td>
</tr>
<% i++; }) %>
<% } else{ %>
<tr>
<td colspan="7">No Data Found</td>
</tr>
<% } %>
</table>
</div>
</body>
</html>
I have used below code but it is not working as i am new i need your guidence
#76484 i have used this ``` {{#if userData.length != 0 }}
{{var i =1;}}
{{userData.forEach(function(data))}}
<tr>
<td>{{=i;}}</td>
<td>{{= data.fullName}}</td>
<td>{{= data.emailAddress}}</td>
<td>{{= data.city}}</td>
<td>{{= data.country}}</td>
<td>{{= data.Dimension_4_Score}}</td>
<td>{{= data.Total_Score_Persentage}}</td>
</tr>
{{i++; })}}
{{else{} }
<tr>
<td colspan="7">No Data Found</td>
</tr>
{{}}}
</table>
</div>
</body> ``` but it is not working
The primary difference between your embedded JS example and Handlebars is that Handlebars does not execute arbitrary JavaScript, like your .forEach loop. Instead, Handlebars provides helpers to allow you to do things like conditionals and iteration.
First, we will tackle your condition, if (userData.length != 0). Handlebars has a #if helper which we could use to check if userData has a truth (greater than 0) length. The result would be:
{{#if userData.length}}
{{! TODO: output each user data}}
{{else}}
<tr>
<td colspan="7">No Data Found</td>
</tr>
{{/if}}
Secondly, Handlebars has an #each helper which is used for looping over collections as you are doing with your userData.forEach(function(data) { /*...*/ } code. For your purposes, the syntax would be:
{{#each userData}}
<tr>
<td>{{ #index }}</td>
<td>{{ fullName }}</td>
<td>{{ emailAddress }}</td>
<td>{{ city }}</td>
<td>{{ country }}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
{{/each}}
Notice how we are evaluating the properties of each object in our userData array. There is no =. We just wrap the property name in double-handlebars, like {{ fullName }}. Handlebars handles the execution context within the #each so that we are always referring to the current iteration of our array.
Also notice the {{ #index }}. This is a special variable provided by Handlebars to give us the current iteration index within our #each loop. It is zero-index, so our output will be slightly different from your ejs example because you initialized your counter at 1.
Unfortunately, if we want our indexes to be one-based, we will have to write a custom helper to this. Our helper would just need to take a number, #index, and increment it by 1. It would look like:
Handlebars.registerHelper('increment', function (num) {
return num + 1;
});
And we would update our template to make use of it:
{{increment #index }}
I have created a fiddle with the final example for your reference.

How do I create reports in Symfony2?

Im creating an application un Symfony2.7 and I want to start creating reports, I have been reading for a couple of days and cant find a solution.
Ive tried ps pdfbundle, but I cant generate reports. Cant find more Documentation.
Please help
My Code:
public function formatoOcAction($id)
{
$facade = $this->get('ps_pdf.facade');
$response = new Response();
$em = $this->getDoctrine()->getManager();
$InOc = $em->getRepository('NivalInventarioBundle:InOrdenCompra')->findById($id);
$InOcDet = $em->getRepository('NivalInventarioBundle:InOrdenCompraDetalle')->findBy(array(
'idOrdenCompra' => $id));
$stylesheetXml = $this->renderView('NivalInventarioBundle:InOrdenCompra:ordencompra.xml.twig', array());
$this->render('NivalInventarioBundle:InOrdenCompra:ordencompra.pdf.twig', array(
"entities1" => $InOc,
"entities2" => $InOcDet,
"id" => $id),
$response);
$xml = $response->getContent();
$content = $facade->render($xml, $stylesheetXml);
$filename = $this->getParameter('upload_directory').'orden_compra_'.$id.'.pdf';
file_put_contents($filename, $content);
return new Response($content, 200, array('content-type' => 'application/pdf'));
}
Where $id is the Id of the purchase order.
This renders a xml file to PDF but without sylesheet.
This is the twig:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pdf SYSTEM "%resources%/dtd/doctype.dtd">
{% set empresa = app.session.get('empresa') %}
<pdf>
<page>
<div>
<div>
<table>
<tr>
<td>
<h3>{{ empresa }}</h3>
</td>
<td id="s1">
<h2>NĂºmero: <b>{{ id }}</b></h2>
</td>
</tr>
<tr>
<td></td>
<td>
<h3>Orden de compra</h3>
</td>
</tr>
<tr>
<td></td>
<td>
Departamento de Finanzas
</td>
</tr>
</table>
</div>
<div>
{% for entity1 in entities1 %}
Fecha: {{ entity1.fecha|date('d-m-Y') }}
{% endfor %}
</div>
</div>
<div>
<div>
<table width="100%">
<tr>
<td width="60%">Producto</td>
<td width="20%">Unidad</td>
<td>Cantidad</td>
<td>Precio</td>
<td>Total</td>
</tr>
{% set gran_total = 0 %}
{% for entity2 in entities2 %}
<tr>
<td>{{ entity2.productoOc.nombre }}</td>
<td>{{ entity2.productoOc.unidadMedida.nombre }}</td>
<td class="text-right">{{ entity2.cantidad }}</td>
<td class="text-right">{{ entity2.precioCompra }}</td>
<td class="text-right">{{ entity2.total }}</td>
</tr>
{% set gran_total = gran_total + entity2.total %}
{% endfor %}
<tr>
<td></td><td></td><td></td><td></td>
<td class="text-right" >{{ gran_total|number_format(2) }}</td>
</tr>
</table>
</div>
</div>
</page>
</pdf>
Maybe look at the KnpSnappyBundle which allow you to generate PDF file from many sources, including twig templates : http://knpbundles.com/KnpLabs/KnpSnappyBundle
You have at least two options to choose from. I found easiest to work with:
Github KnpLabs/snappy as mentioned by Cyrille Hejl
PDF creator from html content, but in your report controller you would have to do all the work of creating:
header html from twig template
footer html from twig template
cover page html from twig template
toc XML from twig template
base document html from twig template
adding all mentioned html docs to object $pdf = $this->get('knp_snappy.pdf');
PROS:
easy to work with Twig html
no memory exhaust if entity object with relations is supplied to Twig (on longer documents)
CONS:
have to supply html files from Twig template for each joined page (cover, toc, header, footer, base doc)
needed tinkering with right wkhtmltopdf binary version
Github mbence/OpenTBSBundle
This is template merger. In your report controller you will have to supply office template and all the variables, that are replaced with TBS at e.g. word template:
it supports OpenOffice and MSOffice templates
PROS:
customer supplies template, you just replace dynamic content with variables (customer takes care of document design)
CONS:
it could run to memory exhaust problems, since PHP script holds all input variables or arrays in memory.
harder to understand than Twig html (longer learning curve)
I recommend to use: WhiteOctoberTCPDFBundle, it's a bundle to facilitate using TCPDF for PDF generation in Symfony2 applications, great to make the reports we need. Please go to: https://github.com/whiteoctober/WhiteOctoberTCPDFBundle

How to import and save data from csv in web2py database table?

I used SQlite database.
I wrote code like this
Module:
db.py
db = DAL('sqlite://storage.sqlite')
db.define_table('data3')
db.data3.import_from_csv_file(open('mypath/test.csv'),'r')
Controller:
def website_list():
return dict(websites = db().select(db.data4.ALL))
View:
{{extend 'layout.html'}}
<h2>List Of Websites</h2>
<table class="flakes-table" style="width:100% ;">
<thead>
<tr>
<td class="id" >ID</a></td>
<td class="link" >Link</td>
</tr>
</thead>
{{for web in websites:}}
<tbody class="list">
<tr>
<td >{{=web.id}}</td>
<td >{{=web.Link}</td>
</tr>{{pass}}
</tbody>
</table>
But it is showing error as
"type 'exceptions.AttributeError'"
Also error has this line
Function argument list
(self=, key='data3')
I think some thing is wrong in reading csv file. My csv file has following data
"Link_Title","Link"
"Apple's Ad Blockers Rile Publishers","somelink"
"Uber Valued at More Than $50 Billion","somelink"
"England to Roll Out Tailored Billboards","somelink"
Can anyone help in this..?

Sorting a Dojo DataGrid Declaratively

I have a DataGrid that is loaded from an XML data store, all created declaratively. I'd like to set the sort when the data is loaded. All of the examples I've found deal with doing this programatically and hint that it should be doable Declaratively.
This is the code that creates the datasource.
<head>
<title>Untitled Page</title>
<style type="text/css">
#import "StyleSheet.css";
#import "js/dojotoolkit/dijit/themes/pfga/pfga.css";
#import "js/dojotoolkit/dojo/resources/dojo.css";
#import "js/dojotoolkit/dojox/grid/resources/Grid.css";
#import "js/dojotoolkit/dojox/grid/resources/pfgaGrid.css";
</style>
<script src="js/dojotoolkit/dojo/dojo.js" type="text/javascript" djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojox.data.XmlStore");
dojo.require("dijit.layout.ContentPane");
</script>
</head>
<body class="pfga">
<div dojotype="dojox.data.XmlStore" url="events.xml" jsID="eventStore"></div>
<table dojoType="dojox.grid.DataGrid" store="eventStore" class="pfga" style="height:500px" clientSort="true" jsID="eventGrid">
<thead>
<tr>
<th field="date" width="80px">Date</th>
<th field="description" width="600">Description</th>
<th field="DateID" sortDesc="true" hidden="false">DateSort</th>
</tr>
<tr>
<th field="time" colspan="3">Details</th>
</tr>
</thead>
</table>
</body>
For the record, in dojo 1.5 it's the 'sortInfo' param passed to the Data Grid. It uses the same convention as the 'canSort' function, i.e. a number indicating the column (starting at 1) and the sign indicating the direction of sort.
I added a comment to http://docs.dojocampus.org/dojox/grid/DataGrid to this effect.
For example, this grid is sorted by the 'created' column in 'most recent first' order:
<table dojoType="dojox.grid.DataGrid" clientSort="true" selectionMode="single"
formatterScope="formatterScope" dojoAttachPoint="logGrid" sortInfo="-2">
<thead><tr>
<th field="clientId" width="10%">Client ID</th>
<th field="created" width="20%" formatter="datefmt">Created</th>
<th field="message" width="30%" formatter="messagebodyfmt">Message</th>
<th field="token" width="10%">Token</th>
<th field="type" width="20%">Type</th>
<th field="username" width="10%">Username</th>
</tr>
</table>
Of course your choice of store and the way it understands the sort directives will have further impact, for example I'm using JsonQueryRestStore and the sortInfo param results in the store query including sort syntax based on dojox.data.JsonQuery and the backend handling the query must understand how to sort the data before returning it.
It looks like the Sort started to work once I added the JSID to solve my filtering problem

Resources