0

Hi so I'm working on writing a custom jinja template that inherits from Pandas base template.

My default template looks as

{% extends "html.tpl" %}
{% block table %}
<style  type="text/css" >
{% block default_table_styles %}
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
{% endblock default_table_styles %}
</style>
{{ super() }}
{% endblock table %}

Now I create a mock dataframe and try to render using my custom template but the effects do not take place.

My mock code for a dataframe

import numpy as np
import pandas as pd
from pandas.io.formats.style import Styler
from IPython.display import HTML
from bs4 import BeautifulSoup as bs
# make complex dataframe
def mklbl(prefix, n):
        return ["%s%s" % (prefix, i) for i in range(n)]
micolumns = pd.MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
                                           ('b', 'foo'), ('b', 'bah')],
                                          names=['lvl0', 'lvl1'])
miindex = pd.MultiIndex.from_product([mklbl('A', 4),
                                      mklbl('B', 2),
                                      mklbl('C', 4),
                                      mklbl('D', 2)], names=['lvl2','lvl3','lvl4','lvl5'])
df = pd.DataFrame(np.arange(len(miindex) * len(micolumns))
                          .reshape((len(miindex), len(micolumns))),
                        index=miindex,
                        columns=micolumns).sort_index().sort_index(axis=1)
df

enter image description here

Making my custom subclass Styler object using Pandas subclass factory function.

EasyStyler = Styler.from_custom_template("path_to_new_tpl_file", "default.tpl")

Now I render

EasyStyler(df)

enter image description here

That should work according my research but it doesn't appear to.

I tried pretty printing the html and it doesn't look like my style block is there at all.

print(bs(EasyStyler(df).render()).prettify())

enter image description here

What I want is for users to be able override the properties of my default template if they so choose. My thinking was that if I include my style block before any of their code then if the user decides to override some style attributes then those will take precedence over mine as they come later.

Edit:

So I was able to get what I want by moving the style container inside of table block. However, I cannot override these settings now.

s = EasyStyler(df)
s.set_table_styles(dict(selector="th", props=[('background-color','red'),('color','white')]))

I was hoping the above would change the background color in the th header but its not. I would love to know how to get this working.

enter image description here

Edit2:

So it seems to be that the parent templates style container gets placed before the childs, causing the child's to overwrite the parents. Is there way to force them the other way perhaps?

enter image description here

Melendowski
  • 404
  • 4
  • 16

1 Answers1

1

So after a lot of reading I discovered the problem.

Two things I learned, as I never worked with css/html before let alone jinja2 templates.

If you look at the template that Pandas provides you'll see they have empty blocks such as before_style and before_table if you call those in your child template that inherits from it, the code you put in those blocks gets executed in that place.

The second mistake I was making was that when I was trying to apply the css to the table. I didn't realize that because the table is the most element I only needed the table id and not the actual word table.

Those two adjustments got me what I wanted completely and the template is still completely overridable from the pandas.io.formats.style.Style subclass.

{% extends "html.tpl" %}
{%- block before_style -%}
<style  type="text/css">
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
</style>
{%- endblock before_style -%}
{%- block before_table -%}
<style>
         #T_{{uuid}} {
          border: black solid thin;
    }
</style>
{%- endblock before_table -%}
{% block table %}
{{ super() }}
{% endblock table %}
Melendowski
  • 404
  • 4
  • 16