Skip to content

Commit

Permalink
Merge pull request #2375 from Avaiga/2366-allow-custom-javascript-fil…
Browse files Browse the repository at this point in the history
…es-for-specific-page

Allow custom Javascript files for specific page
  • Loading branch information
namnguyen20999 authored Jan 13, 2025
2 parents b85c290 + 7b6f170 commit f11fc47
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 3 deletions.
16 changes: 15 additions & 1 deletion frontend/taipy-gui/src/components/pages/TaipyRendered.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface AxiosRenderer {
style: string;
head: HeadProps[];
context: string;
scriptPaths: string[];
}

// set global style the traditional way
Expand All @@ -61,6 +62,18 @@ const setStyle = (id: string, styleString: string): void => {
}
};

// set script tag for the page
const setScript = (id: string, scriptPaths: string[]): void => {
document.querySelectorAll(`script[id^="${id}_"]`).forEach(script => script.remove());
scriptPaths.forEach((path, index) => {
const script = document.createElement("script");
script.id = `${id}_${index}`;
script.src = path;
script.defer = true;
document.head.append(script);
});
};

interface PageState {
jsx?: string;
module?: string;
Expand Down Expand Up @@ -97,9 +110,10 @@ const TaipyRendered = (props: TaipyRenderedProps) => {
if (!fromBlock) {
setStyle(
path == "/TaiPy_root_page" ? "Taipy_root_style" : "Taipy_style",
result.data.style || ""
result.data.style || "",
);
Array.isArray(result.data.head) && setHead(result.data.head);
Array.isArray(result.data.scriptPaths) && setScript("Taipy_script", result.data.scriptPaths);
}
})
.catch((error) => {
Expand Down
2 changes: 2 additions & 0 deletions taipy/gui/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import re
import typing as t
import warnings
from pathlib import Path

from ._warnings import TaipyGuiAlwaysWarning

Expand All @@ -34,6 +35,7 @@ def __init__(self) -> None:
self._style: t.Optional[t.Union[str, t.Dict[str, t.Any]]] = None
self._route: t.Optional[str] = None
self._head: t.Optional[list] = None
self._script_paths: t.Optional[t.Union[str, Path, t.List[t.Union[str, Path]]]] = None

def render(self, gui: Gui, silent: t.Optional[bool] = False):
if self._renderer is None:
Expand Down
3 changes: 2 additions & 1 deletion taipy/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,7 @@ def add_page(
new_page._route = name
new_page._renderer = page
new_page._style = style or page._get_style()
new_page._script_paths = page._get_script_paths()
# Append page to _config
self._config.pages.append(new_page)
self._config.routes.append(name)
Expand Down Expand Up @@ -2571,7 +2572,7 @@ def __render_page(self, page_name: str) -> t.Any:
with self._set_locals_context(context):
self._call_on_page_load(nav_page)
return self._server._render(
page._rendered_jsx, page._style if page._style is not None else "", page._head, context
page._rendered_jsx, page._script_paths if page._script_paths is not None else [], page._style if page._style is not None else "", page._head, context # noqa: E501
)
else:
return ("No page template", 404)
Expand Down
35 changes: 35 additions & 0 deletions taipy/gui/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@

import inspect
import typing as t
from pathlib import Path
from types import FrameType
from urllib.parse import urlparse

from ._warnings import _warn
from .utils import _filter_locals, _get_module_name_from_frame

if t.TYPE_CHECKING:
Expand Down Expand Up @@ -75,6 +78,7 @@ def __init__(self, **kwargs) -> None:
self._notebook_gui: t.Optional["Gui"] = None
self._notebook_page: t.Optional["_Page"] = None
self.set_style(kwargs.get("style", None))
self._script_paths(kwargs.get("script_paths", None))

def create_page(self) -> t.Optional[Page]:
"""Create the page content for page modules.
Expand Down Expand Up @@ -180,3 +184,34 @@ def set_style(self, style: t.Dict[str, t.Dict[str, t.Any]]) -> Page:

def _get_style(self):
return self.__style

def _script_paths(self, script_paths: t.Optional[t.Union[str, Path, t.List[t.Union[str, Path]]]]) -> Page:
"""
Load a script or a list of scripts to be used in the page.
Arguments:
script_paths (str, Path, list): The path to the script file or a list of paths to the script files.
Returns:
This `Page` instance.
"""
if script_paths:
if isinstance(script_paths, (str, Path)):
script_paths = [script_paths]
for script_path in script_paths:
if isinstance(script_path, str):
parsed_url = urlparse(script_path)
if parsed_url.netloc:
continue
script_path = Path(script_path)

if isinstance(script_path,
Path) and script_path.exists() and script_path.is_file() and script_path.suffix == ".js":
continue
else:
_warn(f"Script path '{script_path}' does not exist, is not a file, or is not a JavaScript file.")
self.__script_paths = script_paths if script_paths else None
return self

def _get_script_paths(self):
return self.__script_paths
3 changes: 2 additions & 1 deletion taipy/gui/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def my_index(path):
return taipy_bp

# Update to render as JSX
def _render(self, html_fragment, style, head, context):
def _render(self, html_fragment, script_paths, style, head, context):
template_str = _Server.__RE_OPENING_CURLY.sub(_Server.__OPENING_CURLY, html_fragment)
template_str = _Server.__RE_CLOSING_CURLY.sub(_Server.__CLOSING_CURLY, template_str)
template_str = template_str.replace('"{!', "{")
Expand All @@ -252,6 +252,7 @@ def _render(self, html_fragment, style, head, context):
"style": (style + os.linesep) if style else "",
"head": head or [],
"context": context or self._gui._get_default_module_name(),
"scriptPaths": script_paths
}
)

Expand Down

0 comments on commit f11fc47

Please sign in to comment.