Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5aaa249
including notes
elnelson575 Aug 25, 2025
cc15245
Removing notes to self
elnelson575 Aug 25, 2025
e6b8260
cleanup
elnelson575 Aug 25, 2025
0fb5ccf
Merge branch 'main' into fix/js_css_inclusion
elnelson575 Aug 25, 2025
f4c53fd
With prints
elnelson575 Aug 26, 2025
2764cbe
Add multifile example, notes
elnelson575 Aug 26, 2025
03839f0
Fixing types
elnelson575 Aug 26, 2025
649c856
Merge branch 'fix/js_css_inclusion' of github.com:posit-dev/py-shiny …
elnelson575 Aug 26, 2025
c1a11a1
Updating tests
elnelson575 Aug 27, 2025
ff8581e
Debugging
elnelson575 Aug 27, 2025
c888903
fixes
elnelson575 Aug 27, 2025
e99f795
Deleting old test
elnelson575 Aug 27, 2025
c1d7568
Merging in changes from other branch
elnelson575 Aug 27, 2025
14012c8
Added comments, minor changes
elnelson575 Aug 28, 2025
7ffeab5
Relinking vs inline
elnelson575 Aug 28, 2025
63a3c40
Update shiny/ui/_include_helpers.py
elnelson575 Aug 28, 2025
6609d20
Updating prints
elnelson575 Aug 28, 2025
b477812
Updating 'shiny_include_files to have 777 perms
elnelson575 Aug 29, 2025
30fc4f7
Testing only new dir change
elnelson575 Sep 2, 2025
87afb30
Updating to deal with 404
elnelson575 Sep 3, 2025
8ae6460
Updating one missing piece
elnelson575 Sep 3, 2025
74c931e
Removing prints
elnelson575 Sep 4, 2025
26fedcc
Updatign changelog
elnelson575 Sep 4, 2025
b48aea9
Minor edit
elnelson575 Sep 4, 2025
88a9fee
Merge branch 'main' into fix/js_css_include_perms
elnelson575 Sep 4, 2025
e4fea42
Updating tests
elnelson575 Sep 4, 2025
cee6f3e
Updated changelog and comment placement
elnelson575 Sep 4, 2025
9004f58
Updating test name
elnelson575 Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions shiny/ui/_include_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# as the app, the app's source will be included. Should we just not copy .py/.r files?


# TODO: This does throw js errors if you're loading in other stuff depending on your config
@add_example()
def include_js(
path: Path | str,
Expand Down Expand Up @@ -214,37 +215,62 @@ def create_include_dependency(

def maybe_copy_files(path: Path | str, include_files: bool) -> tuple[str, str]:
hash = get_hash(path, include_files)
print("path: ", path, "Hash: ", hash)

# To avoid unnecessary work when the same file is included multiple times,
# use a directory scoped by a hash of the file.
tmpdir = os.path.join(tempfile.gettempdir(), "shiny_include_files", hash)
path_dest = os.path.join(tmpdir, os.path.basename(path))
print("path_dest:", path_dest)

# Since the hash/tmpdir should represent all the files in the path's directory,
# we can simply return here
# we can check if it exists to determine if we have a cache hit
if os.path.exists(path_dest):
print("Already exists", path_dest)
return path_dest, hash

permissions = (
0o755 # Store permissions var set to -rwxr-xr-x (owner rwx, others rx)
)

# Otherwise, make sure we have a clean slate
if os.path.exists(tmpdir):
print("folder exists, not contents:", os.stat(tmpdir))
shutil.rmtree(tmpdir)

# Looks like this is copying twice? puts stuff in diff folders?
if include_files:
shutil.copytree(os.path.dirname(path), tmpdir)
else:
os.makedirs(tmpdir, exist_ok=True)
shutil.copy(path, path_dest)
print("new folder, perms: ", oct(os.stat(tmpdir).st_mode))
for root, dirs, files in os.walk(tmpdir):
# set perms on sub-directories
for dir in dirs:
os.chmod(os.path.join(root, dir), permissions)
print("Dir: ", dir)
print("dir perms: ", oct(os.stat(os.path.join(root, dir)).st_mode))

# set perms on files
for file in files:
print("File: ", file)
os.chmod(os.path.join(root, file), permissions)
print("file perms: ", oct(os.stat(os.path.join(root, file)).st_mode))

shutil.copy(path, path_dest)
print("PATH_DEST: ", path_dest)
return path_dest, hash


def get_hash(path: Path | str, include_files: bool) -> str:
if include_files:
key = get_file_key(path)
else:
print("get_hash, include_files is true")
dir = os.path.dirname(path)
files = glob.iglob(os.path.join(dir, "**"), recursive=True)
key = "\n".join([get_file_key(x) for x in files])
print("KEY: ", key)
else:
key = get_file_key(path)
print("not include key: ", key)

return hash_deterministic(key)


Expand Down
24 changes: 24 additions & 0 deletions tests/playwright/shiny/bugs/2061-css-js-inclusion/app-lite/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from shiny import App, ui

# Define the UI
app_ui = ui.page_fluid(
ui.include_css(
"./www/style.css", method="link_files"
), # Reference the external CSS file
ui.include_js("./www/customjs.js"),
ui.h1("Simple Shiny App with External CSS"),
ui.div(
ui.p("This is a simple Shiny app that demonstrates ui.include_css()"),
ui.p("The styling comes from an external CSS file!"),
class_="content",
),
)


# Define the server
def server(input, output, session):
pass


# Create and run the app
app = App(app_ui, server)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("heyo")
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

body {
background-color: #f0f8ff;
font-family: Arial, sans-serif;
}

h1 {
color: #4682b4;
border-bottom: 2px solid #4682b4;
padding-bottom: 10px;
}

.content {
margin: 20px;
padding: 15px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
22 changes: 22 additions & 0 deletions tests/playwright/shiny/bugs/2061-css-js-inclusion/app-multi/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from shiny import App, ui

# Define the UI
app_ui = ui.page_fluid(
ui.include_css("./css/style.css", method="link_files"),
ui.include_js("./js/customjs.js", method="link_files"),
ui.h1("Simple Shiny App with External CSS"),
ui.div(
ui.p("This is a simple Shiny app that demonstrates ui.include_css()"),
ui.p("The styling comes from an external CSS file!"),
class_="content",
),
)


# Define the server
def server(input, output, session):
pass


# Create and run the app
app = App(app_ui, server)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
background-color: #506577;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import url("more.css");

body {
font-family: Arial, sans-serif;
}

h1 {
color: #4682b4;
border-bottom: 2px solid #4682b4;
padding-bottom: 10px;
}

.content {
margin: 20px;
padding: 15px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const heyo = require('./more.js');


console.log(heyo())
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function heyo() {
console.log(heyo)
}
Loading