Introducing HTML/CSS templates

hi lubos
how can i put the footer notes in html i tried but couldn’t work still the notes hanging in the main body and the invoice is a4

my html values

<table style="width: 100%">
    <thead>
        <tr>
            <td style="font-size: 36px; font-weight: bold; vertical-align: top; line-height: 36px">{{ strings.invoice }}</td>
            <td style="text-align: right">{% if business.logo != null %}<img src="{{ business.logo }}" style="max-width: 300px; max-height: 150px">{% endif %}</td>
        </tr>
        <tr>
            <td colspan="2" style="padding: 20px 0px">
                <table style="width: 100%">
                    <tr>
                        <td style="vertical-align: top; font-weight: bold; width: 1px; white-space: nowrap; padding-right: 10px; padding-top: {{ window_faced_envelope.vertical_padding }}px">
                            {{ strings.to }}
                        </td>
                        <td style="vertical-align: top; padding-top: {{ window_faced_envelope.vertical_padding }}px; padding-left: {{ window_faced_envelope.horizontal_padding }}px">
                            <div><b>{{ customer.name }}</div>
                            <div>{{ billing_address | newline_to_br }}</div>
                            <div>{{ customer.identifier }}</div>
                        </td>
                        <td style="vertical-align: top; width: 100px; padding-right: 20px; vertical-align: top; text-align: right">
                            <div style="font-weight: bold">{{ strings.issue_date }}</div>
                            <div>{{ issue_date | date_to_string }}</div>
                            {% if due_date != null %}
                            <div style="font-weight: bold; margin-top: 10px">{{ strings.due_date }}</div>
                            <div>{{ due_date | date_to_string }}</div>
                            {% endif %}
                            <div style="font-weight: bold; margin-top: 10px; white-space: nowrap">{{ strings.invoice_number }}</div>
                            <div>{{ reference }}</div>
                            {% if sales_quote != empty %}
                            <div style="font-weight: bold; margin-top: 10px; white-space: nowrap">{{ strings.sales_quote }}</div>
                            <div>{{ sales_quote }}</div>
                            {% endif %}
                            {% if purchase_order != empty %}
                            <div style="font-weight: bold; margin-top: 10px; white-space: nowrap">{{ strings.purchase_order }}</div>
                            <div>{{ purchase_order }}</div>
                            {% endif %}
                        </td>
                        <td style="vertical-align: top; width: 100px; border-left: 1px solid #000; padding-left: 20px; vertical-align: top">
                            <div style="font-weight: bold; white-space: nowrap">{{ business.name }}</div>
                            <div style="font-style: normal; white-space:nowrap">{{ business.contact_information | newline_to_br }}</div>
                            <div style="white-space: nowrap">{{ business.identifier }}</div>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td colspan="2">
                <div style="font-weight: bold; padding-bottom: 20px; font-size: 14px">{{ summary }}</div>
                <table style="width: 100%">
                    <tr>
                        {% if has_item %}<th style="border: 1px solid #000; padding: 5px 10px">{{ strings.item }}</th>{% endif %}
                        <th style="border: 1px solid #000; padding: 5px 10px">{{ strings.description }}</th>
                        {% if has_qty %}<th style="width: 40px; border: 1px solid #000; padding: 5px 10px; text-align: center">{{ strings.qty }}</th>{% endif %}
                        {% if has_qty %}<th style="width: 80px; border: 1px solid #000; padding: 5px 10px; text-align: center">{{ strings.unit_price }}</th>{% endif %}
                        {% if has_discount %}<th style="width: 60px; border: 1px solid #000; padding: 5px 10px; text-align: center">{{ strings.discount }}</th>{% endif %}
                        {% if distinct_taxes > 1 %}<th style="width: 40px; border: 1px solid #000; padding: 5px 10px; text-align: center">{{ strings.tax }}</th>{% endif %}
                        <th style="width: 100px; border: 1px solid #000; padding: 5px 10px; text-align: center">{{ strings.amount }}</th>
                    </tr>
                    {% for line in lines %}
                    <tr>
                        {% if has_item %}<td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none; vertical-align: top">{{ line.item.name }}</td>{% endif %}
                        <td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none">{{ line.description | newline_to_br }}</td>
                        {% if has_qty %}<td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none; text-align: center; vertical-align: top">{{ line.qty }}</td>{% endif %}
                        {% if has_qty %}<td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none; text-align: right; vertical-align: top">{{ line.unit_price | money_without_currency }}</td>{% endif %}
                        {% if has_discount %}<td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none; text-align: center; vertical-align: top">{% if line.discount != null %}{{ line.discount }} %{% endif %}</td>{% endif %}
                        {% if distinct_taxes > 1 %}<td style="border: 1px solid #000; padding: 5px 10px; border-bottom: none; border-top: none; text-align: center; vertical-align: top; white-space: nowrap">{% if line.tax %}{{ line.tax.code }}{% else %}-{% endif %}</td>{% endif %}
                        <td style="border: 1px solid #000; padding: 5px 10px; text-align: right; border-bottom: none; border-top: none; vertical-align: top; white-space: nowrap">{{ line.total | money_without_currency }}</td>
                    </tr>
                    {% endfor %}
                    <tr>
                        {% if has_item %}<td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>{% endif %}
                        <td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>
                        {% if has_qty %}<td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>{% endif %}
                        {% if has_qty %}<td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>{% endif %}
                        {% if has_discount %}<td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>{% endif %}
                        {% if distinct_taxes > 1 %}<td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>{% endif %}
                        <td style="border: 1px solid #000; padding: 5px 10px; border-top: none">&nbsp;</td>
                    </tr>

                  {% assign colspan = 1 %}
                  {% if has_item %}{% assign colspan = colspan | plus:1 %}{% endif %}
                  {% if has_qty %}{% assign colspan = colspan | plus:2 %}{% endif %}
                  {% if has_discount %}{% assign colspan = colspan | plus:1 %}{% endif %}
                  {% if distinct_taxes > 1 %}{% assign colspan = colspan | plus:1 %}{% endif %}

                  {% if amounts_include_tax %}
                    {% if rounding != 0 %}
                    <tr>
                        <td colspan="{{colspan}}" style="text-align: right; padding: 5px 10px">Round off</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; white-space: nowrap">{{ rounding | money }}</td>
                    </tr>
                    {% endif %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px; font-weight: bold">{{ strings.total }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; font-weight: bold; white-space: nowrap">{{ total | money }}</td>
                    </tr>
                    {% for tax_component in tax_components %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px">{{ tax_component.code }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; white-space: nowrap">{{ tax_component.amount | money }}</td>
                    </tr>
                  {% endfor %}
                  {% else %}
                    {% assign tax_components_count = tax_components | size %}
                    {% if tax_components_count > 0 %}
                    <tr>
                      <td colspan="{{colspan}}" style="text-align: right; padding: 5px 10px; font-weight: bold">{{ strings.subtotal }}</td>
                      <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; font-weight: bold; white-space: nowrap">{{ subtotal | money }}</td>
                    </tr>
                    {% endif %}
                    {% for tax_component in tax_components %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px">{{ tax_component.code }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; white-space: nowrap">{{ tax_component.amount | money }}</td>
                    </tr>
                    {% endfor %}
                    {% if rounding != 0 %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px">Rounding</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; white-space: nowrap">{{ rounding | money }}</td>
                    </tr>
                    {% endif %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px; font-weight: bold">{{ strings.total }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; font-weight: bold; white-space: nowrap">{{ total | money }}</td>
                    </tr>
                    {% endif %}
                    {% if amount_credited != 0 %}
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px">{{ strings.amount_credited }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; white-space: nowrap">{{ amount_credited | money }}</td>
                    </tr>
                    <tr>
                        <td colspan="{{colspan}}"  style="text-align: right; padding: 5px 10px; font-weight: bold">{{ strings.balance_due }}</td>
                        <td style="border: 1px solid #000; text-align: right; padding: 5px 10px; font-weight: bold; white-space: nowrap">{{ balance_due | money }}</td>
                    </tr>
                    {% endif %}
                </table>
                <div>{{ notes }}</div>
                
                {% if balance_due < 0 %}
                <div style="text-align: center; margin-top: 40px; margin-bottom: 80px"><span style="color: red; border: 10px solid red; padding: 10px; font-size: 40px; font-weight: bold; transform:rotate(-15deg); -ms-transform:rotate(-15deg); -moz-transform:rotate(-15deg); -webkit-transform:rotate(-15deg); -o-transform:rotate(-15deg);">{{ strings.overpaid | capitalize }}</span></div>
                {% endif %}
                
                {% if balance_due > 0 %}
                <div>{{ terms_and_payment_advice }}</div>
                  {% if overdue %}
                    <div style="text-align: center; margin-top: 40px; margin-bottom: 80px"><span style="color: red; border: 5px solid red; padding: 10px; font-size: 20px; transform:rotate(-15deg); -ms-transform:rotate(-15deg); -moz-transform:rotate(-10deg); -webkit-transform:rotate(-10deg); -o-transform:rotate(-10deg);">{{ strings.overdue | capitalize }}</span></div>
                  {% endif %}

                  {{ payment_advice_cutaway }}
                {% endif %}

                {% if balance_due == 0 %}
                  <div style="text-align: center; margin-top: 40px; margin-bottom: 80px"><span style="color: darkgreen; border: 5px solid darkgreen; padding: 10px; font-size: 20px; transform:rotate(10deg); -ms-transform:rotate(10deg); -moz-transform:rotate(10deg); -webkit-transform:rotate(10deg); -o-transform:rotate(10deg);">{{ strings.paid_in_full | capitalize }}</span></div>
                {% endif %}
                
            </td>
        </tr>
    </tbody>
</table>






<p><b>Prepared by :..................................................... <c><b>Received by :.................................................. <r><b>Signed  by :.....................
<div id="footer"></div><b></b>FOR DIRECT DEPOSIT OR TRANSFER PLEASE FIND OUR BANKING DETAILS BELOW:</b></p>

<div id="footer"></div>ACCOUNT NAME:KIBO CUISINE LTD. 

<div id="footer"></div>BANK:DTB BANK LTD 

<div id="footer"></div>ACCOUNT NUMBER:

<div id="footer"></div>TSHS: 0047905001

<div id="footer"></div>USD: 0047905002

<div id="footer"></div>SWIFT BIC:DTKETZTZ 

<div id="footer"></div>BRANCH SORT CODE: 011

<div id="footer"></div>PLEASE WRITE CHEQUES PAYABLE ONLY TO: KIBO CUISINE LTD.

<div id="footer"></div><b><i> THANK YOU FOR YOUR BUSINESS</i>

Bonita, are you asking why the notes aren’t appearing at the bottom of the page? If you’re entering these in the ‘Notes’ field of each invoice, they will appear in this part of your code:

<div>{{ notes }}</div>

If your payment instructions are the same on every invoice and you don’t mind customising the template, you could also just add them to the HTML, e.g:

<div>
<p>FOR DIRECT DEPOSIT OR TRANSFER PLEASE FIND OUR BANKING DETAILS BELOW:</p>
<p>ACCOUNT NAME:KIBO CUISINE LTD.</p>
…
</div>

As to how to get this div to the bottom of the page, that’s done with CSS positioning, and it’s probably a bit much to expect Lubos to teach us all CSS! Plenty of online resources for learning how to do this.

@Kal thanks i was able to sort it out

It’s definitely possible. I might need to introduce some extra variables so you can differentiate between line items of different type based on general ledger account used.

Then it’s a matter of having two tables looping through all line items while skipping those which are not appropriate.

This is standard feature of LiquidMarkup

Have a look at Liquid filters

1 Like

Thank you. I’ve tried using the date filter as described on that page, but I can’t get it to work. I’ve tried:

{{ issue_date | date: "%-d %B %Y" }}

I’m expecting this to give me ‘1 January 2015’, but instead I’m getting ‘-1 B Y’

Am I doing something wrong?

Edit: @lubos, this question got a little buried in the thread and I’m just wondering if you have a moment to look at this. Many thanks.

@bonita, your invoice looks great! Any chance you can share the code you used to make the footer stick to the bottom please?

I’ve been trying for about an hour with no success!

thanks

@geek_patrol i did that but the footer is hidden it’s visible when you print

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Header & Footer test</title>

<style>

  @media screen {
    div#footer_wrapper {
      display: none;
    }
  }

  @media print {
    tfoot { visibility: show; }

    div#footer_wrapper {
      margin: 0px 2px 0px 7px;
      position: fixed;
      bottom: 0;
    }

    div#footer_content {
      font-weight: bold;
    }
  }

</style>
</head>

<body>

<div id="footer_wrapper">
  <div id="footer_content">
  </div>
</div>

@bonita thanks for the response! I don’t really know what you mean though.

I’ve seen your code for your footer:

<p><b>Prepared by :..................................................... <c><b>Received by :.................................................. <r><b>Signed  by :.....................
<div id="footer"></div><b></b>FOR DIRECT DEPOSIT OR TRANSFER PLEASE FIND OUR BANKING DETAILS BELOW:</b></p>

<div id="footer"></div>ACCOUNT NAME:KIBO CUISINE LTD. 

<div id="footer"></div>BANK:DTB BANK LTD 

<div id="footer"></div>ACCOUNT NUMBER:

<div id="footer"></div>TSHS: 0047905001

<div id="footer"></div>USD: 0047905002

<div id="footer"></div>SWIFT BIC:DTKETZTZ 

<div id="footer"></div>BRANCH SORT CODE: 011

<div id="footer"></div>PLEASE WRITE CHEQUES PAYABLE ONLY TO: KIBO CUISINE LTD.

<div id="footer"></div><b><i> THANK YOU FOR YOUR BUSINESS</i>

but when i put anything like this in my invoice template it floats under the table like your original post.

how did you make it stick to the bottom of the page like in your second image?

Thanks

@geek_patrol: I’ve no idea how bonita ended up doing it, but the usual way to position anything is with CSS positioning. This was the first hit when I Googled it: CSS Layout - The position Property

The way I did it on my template…

First, I defined an overall size for my page:

#body {
	position: relative;
	width: 210mm;
	height: 297mm;
	margin: 0;
	padding: 16mm 15mm 10mm 15mm;
	background-color: white;
}

This gives the footer something to go to the bottom of!

Then, I positioned the footer div 10 mm from the bottom of the page:

#invoice_footer {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 10mm;
}

I really recommend you invest a fair bit of time (i.e. a lot more than ‘about an hour’!) reading up on HTML and CSS though before you tackle your own template modifications. There’s an awful lot to it.

As a side note, that code you copied from bonita… I hadn’t looked closely at it before now, but it’s invalid HTML. Firstly, you should never use the same ID more than once, as has been done here. There should only be one ‘footer’ ID. If you want to use the same selector more than once, you need to use CLASS, not ID. But here it looks like you’d be better served by wrapping the whole footer in the ‘footer’ ID, and separating with paragraphs or line breaks. Secondly, the text is sitting outside the empty divs, which is quite odd.

Morning @kal!

Many thanks for your response.

I spent all afternoon trying to get this to work. It was only after an hour of trying various online tutorials, as well as my own ingenuity, that I thought I’d ask on these forums for an answer, especially as in this post someone had solved the exact same issue I was having but hadn’t posted how they had solved it!

I know a little HTML and CSS, but the amount of time I spend using it doesn’t warrant me investing a great deal of time learning more of it, just for me to forget it because I don’t use it!. Once I’ve got my invoice laid out the way I want it, I’ll hopefully never need to change it, except to change the actual content, addresses, images etc.

The problem I’m having is that I can write some basic CSS, but I would usually put that in a CSS file that is referenced by my HTML. If I write CSS directly into my invoice template (as you’ve provided above), it just comes out as plain text on the invoice. If I reference my CSS file (eg <link rel=StyleSheet href="/home/geek-patrol/stylesheet.css" type="text/css">) within a set of <head> tags it doesn’t work. Are the <head> tags included in another part of another template somewhere else? The <body> tags aren’t present in the invoice template either.

If I put all the CSS in a style attribute within a <body style="..."> tag it applies some formatting (font-family, text-align etc) but not the positioning.

All in all it’s not very intuitive and the turorials on the Manager.io guides don’t provide a great deal of information. On top of that, a lot of the links to guides that @lubos references don’t work any more, they just redirect to the homepage!

After another 2 hours spent learning CSS and experimenting, I’ve managed to position a ‘footer’ element at the bottom of the page using absolute positioning:

`

Footer Content

`

and this works fine for the first page, as long as the invoice items don’t creep into the same area on the page as my footer. If the invoice goes into a 2nd page then the ‘footer’ remains on the first page only.

I can set the ‘footer’ div as relative, but then it appears directly below the table containing my invoice items, so isn’t rely a footer, just a note. Confused!

Quick tip for writing your CSS - you don’t need <head> tags or a reference to an external CSS file. You can however still block all your styling elements together, keeping them out of the HTML code as is good practice.

At the top of your template, before any HTML, use the <style> tags to contain your CSS as follows in this brief example:

<style type="text/css">
    div#footer {
        position:absolute;
        top:282mm;
        }
</style>

As I say, you can put all your CSS within those <style> tags making it much easier to tweak and amend things later should you need to, rather than hunting through your HTML to find the relevant code.

You can also use classes in your HTML elements (e.g., <div class="heading_text">blah blah blah</div>) to reference the same formatting in multiple parts of your document, reducing repetition and the chance of error and again making a change much simpler. In your CSS, # represents an element’s ID (which as mentioned @Kal should only appear once in your document); . represents a class (which can occur many times).

Hope that helps.

2 Likes

[quote=“geek_patrol, post:76, topic:1221, full:true”]Morning @kal!

Many thanks for your response.
[/quote]

Night time over this side of the world! But you’re most welcome. :smile:

Yes, I normally link to an external stylesheet too, but with Manager I thought it would be simpler to just have all the code within the one file. (I’m assuming you can use absolute links but why bother?)

[quote=“geek_patrol, post:76, topic:1221, full:true”]Are the <head> tags included in another part of another template somewhere else? The <body> tags aren’t present in the invoice template either.
[/quote]

I can’t say what magic happens behind the scenes, but I took note that the template didn’t have head or body tags too, and left them out of my template. But that’s fine, you can still include an internal style sheet as you can in any HTML page, using the style tag:

<style>
	#body {
		position: relative;
		width: 210mm;
		height: 297mm;
	}
	...
</style>

Put that anywhere you like. It doesn’t really matter. I certainly prefer this to inline style all through my HTML.

Yes, I’ve noticed that too, and I agree, it makes it hard to find stuff. It looks like they changed the guides recently, and changed the address to: http://guides.manager.io. I simply haven’t been able to find some of the pages that lubos referenced in older forum posts anymore. You can still see an older version of the guide here, but it seems to be missing stuff too: http://www.manager.io/guides/summary

Ah, well this gets into an area I’m completely unfamiliar with: multiple-page invoices. I don’t think I’ve ever had an invoice go to more than one page, so it’s something I haven’t had to worry about.

Yes, with relative positioning, the element continues to be part of the normal flow, i.e. it comes after whatever element came before it. You can move it, relative to that position, but this gets confusing quickly. If you want your footer to be positioned relative to the containing page, then I suggest you give it absolute positioning, and place it within a containing element, which is exactly what you did in your sample code. For the most predictable results, the containing element should have position set to absolute or relative.

2 Likes

[quote=“BGPS, post:78, topic:1221, full:true”]
Quick tip for writing your CSS - you don’t need <head> tags or a reference to an external CSS file. You can however still block all your styling elements together, keeping them out of the HTML code as is good practice.[/quote]

Ah, you beat me to it while I was writing my comment! :slight_smile:

1 Like

@kal and @BGPS thanks for your help guys. I’m making some progress!

I’ve inserted the <style> element as suggested and a strange things happens - the font-family that I’ve chosen for my invoice is applied to all the titles and buttons in Manager! Is this supposed to happen??

It’s a by-product of how Manager works - the interface is also coded in HTML so if you apply a style too broadly, it’ll affect Manager itself.

What you could do is put your invoice in a wrapper DIV and then apply the font-family to that wrapper element. it should then only apply to everything in the wrapper.

For example …

<style type="text/css">
  div#my_inv {
      font-family:tahoma;
      }
</style>
<div id="my_inv">
  <!-- all invoice HTML here -->
</div>
2 Likes

Yep. I discovered the same thing, as you can see from my comment 6 days ago, when I experimented with global styles using the asterisk wildcard. I’m also seeing some issues in the other direction, where Manager styles seem to be conflicting with my own styles. I suggested it would be nice if the templating system was sandboxed, which Lubos said could be done with IFRAME, but he isn’t yet ready to deal with the issues that would create. So for now, we have to find workarounds, but thankfully they’re not too hard.

I’m guessing you were applying your font styles to the body tag. As BGPS explained, the solution is easy. You will have seen in my previous examples, I gave my wrapper DIV the ID ‘body’. All that’s needed then, is to change your CSS selectors from ‘body’ to ‘#body’. Done! :slight_smile:

Hi @lubos,

Do you already found a solution to get rid of the margin / padding around the invoice template?

Thanks

Dear sir thanks for great service, we have pre printed invoice only I want item code Discription price total customer name issue date without heading…

You will need to create a custom view template from scratch. If you don’t have the HTML/CSS skill to do this, you will need to hire someone to do it for you.