{{ super() }}
diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst
index 49c168cd5eb84..0641b32383125 100644
--- a/doc/source/whatsnew/v1.3.0.rst
+++ b/doc/source/whatsnew/v1.3.0.rst
@@ -707,6 +707,7 @@ Other API changes
- Added new ``engine`` and ``**engine_kwargs`` parameters to :meth:`DataFrame.to_sql` to support other future "SQL engines". Currently we still only use ``SQLAlchemy`` under the hood, but more engines are planned to be supported such as `turbodbc `_ (:issue:`36893`)
- Removed redundant ``freq`` from :class:`PeriodIndex` string representation (:issue:`41653`)
- :meth:`ExtensionDtype.construct_array_type` is now a required method instead of an optional one for :class:`ExtensionDtype` subclasses (:issue:`24860`)
+- :meth:`.Styler.from_custom_template` now has two new arguments for template names, and removed the old ``name``, due to template inheritance having been introducing for better parsing (:issue:`42053`). Subclassing modifications to Styler attributes are also needed.
.. _whatsnew_130.api_breaking.build:
diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py
index 00c18ac261bab..06e5ba3fad460 100644
--- a/pandas/io/formats/style.py
+++ b/pandas/io/formats/style.py
@@ -2550,23 +2550,35 @@ def highlight_quantile(
)
@classmethod
- def from_custom_template(cls, searchpath, name):
+ def from_custom_template(
+ cls, searchpath, html_table: str | None = None, html_style: str | None = None
+ ):
"""
Factory function for creating a subclass of ``Styler``.
- Uses a custom template and Jinja environment.
+ Uses custom templates and Jinja environment.
+
+ .. versionchanged:: 1.3.0
Parameters
----------
searchpath : str or list
Path or paths of directories containing the templates.
- name : str
- Name of your custom template to use for rendering.
+ html_table : str
+ Name of your custom template to replace the html_table template.
+
+ .. versionadded:: 1.3.0
+
+ html_style : str
+ Name of your custom template to replace the html_style template.
+
+ .. versionadded:: 1.3.0
Returns
-------
MyStyler : subclass of Styler
- Has the correct ``env`` and ``template`` class attributes set.
+ Has the correct ``env``,``template_html``, ``template_html_table`` and
+ ``template_html_style`` class attributes set.
"""
loader = jinja2.ChoiceLoader([jinja2.FileSystemLoader(searchpath), cls.loader])
@@ -2575,7 +2587,10 @@ def from_custom_template(cls, searchpath, name):
# error: Invalid base class "cls"
class MyStyler(cls): # type:ignore[valid-type,misc]
env = jinja2.Environment(loader=loader)
- template_html = env.get_template(name)
+ if html_table:
+ template_html_table = env.get_template(html_table)
+ if html_style:
+ template_html_style = env.get_template(html_style)
return MyStyler
diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py
index 054dd443bd657..616b89f9e519f 100644
--- a/pandas/io/formats/style_render.py
+++ b/pandas/io/formats/style_render.py
@@ -67,6 +67,8 @@ class StylerRenderer:
loader = jinja2.PackageLoader("pandas", "io/formats/templates")
env = jinja2.Environment(loader=loader, trim_blocks=True)
template_html = env.get_template("html.tpl")
+ template_html_table = env.get_template("html_table.tpl")
+ template_html_style = env.get_template("html_style.tpl")
template_latex = env.get_template("latex.tpl")
def __init__(
@@ -120,7 +122,11 @@ def _render_html(self, sparse_index: bool, sparse_columns: bool, **kwargs) -> st
# TODO: namespace all the pandas keys
d = self._translate(sparse_index, sparse_columns)
d.update(kwargs)
- return self.template_html.render(**d)
+ return self.template_html.render(
+ **d,
+ html_table_tpl=self.template_html_table,
+ html_style_tpl=self.template_html_style,
+ )
def _render_latex(self, sparse_index: bool, sparse_columns: bool, **kwargs) -> str:
"""
diff --git a/pandas/io/formats/templates/html.tpl b/pandas/io/formats/templates/html.tpl
index 880c78c8d6b05..8c63be3ad788a 100644
--- a/pandas/io/formats/templates/html.tpl
+++ b/pandas/io/formats/templates/html.tpl
@@ -1,16 +1,16 @@
-{# Update the template_structure.html documentation too #}
+{# Update the html_style/table_structure.html documentation too #}
{% if doctype_html %}
-{% if not exclude_styles %}{% include "html_style.tpl" %}{% endif %}
+{% if not exclude_styles %}{% include html_style_tpl %}{% endif %}
-{% include "html_table.tpl" %}
+{% include html_table_tpl %}
{% elif not doctype_html %}
-{% if not exclude_styles %}{% include "html_style.tpl" %}{% endif %}
-{% include "html_table.tpl" %}
+{% if not exclude_styles %}{% include html_style_tpl %}{% endif %}
+{% include html_table_tpl %}
{% endif %}
diff --git a/pandas/tests/io/formats/style/test_html.py b/pandas/tests/io/formats/style/test_html.py
index 1ef5fc3adc50e..495dc82f0e7bd 100644
--- a/pandas/tests/io/formats/style/test_html.py
+++ b/pandas/tests/io/formats/style/test_html.py
@@ -41,8 +41,8 @@ def test_html_template_extends_options():
# to understand the dependency
with open("pandas/io/formats/templates/html.tpl") as file:
result = file.read()
- assert '{% include "html_style.tpl" %}' in result
- assert '{% include "html_table.tpl" %}' in result
+ assert "{% include html_style_tpl %}" in result
+ assert "{% include html_table_tpl %}" in result
def test_exclude_styles(styler):
@@ -223,24 +223,46 @@ def test_block_names(tpl_style, tpl_table):
assert result2 == expected_table
-def test_from_custom_template(tmpdir):
- p = tmpdir.mkdir("templates").join("myhtml.tpl")
+def test_from_custom_template_table(tmpdir):
+ p = tmpdir.mkdir("tpl").join("myhtml_table.tpl")
p.write(
dedent(
"""\
- {% extends "html.tpl" %}
- {% block table %}
-