Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions app/Views/home.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<div>
<img src="{{ assets('img/logo.png') }}" alt="SproutPHP Logo" class="main-logo"/>
<h1 class="main-title">{{ config('app.name', 'SproutPHP') }}</h1>
<div class="main-version">
<code class="main-version">
<span>{{ getLatestRelease }}</span>
&mdash;
<span style="text-transform:capitalize">{{ config('app.env', 'local') }}</span>
environment
</div>
</code>
<p class="main-desc">Welcome to
<strong>SproutPHP</strong>, the seed-to-plant minimal PHP framework 🌱<br>HTMX-ready, JS-optional, and developer-happy.</p>
<div class="main-links">
Expand Down
14 changes: 13 additions & 1 deletion app/Views/layouts/base.twig
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,18 @@
background: var(--primary);
color: #fff;
}
.htmx-active {
z-index: 9999;
position: fixed;
bottom: 63px;
right: 10px;
background: #eef;
border: 1px solid #ccd;
padding: 0.5rem;
font-family: monospace;
font-size: 0.8rem;
border-radius: 4px;
}
#sprout-btn {
position: relative;
overflow: hidden;
Expand Down Expand Up @@ -373,7 +385,7 @@
</main>

{% if config('app.env', 'local') == 'local' %}
<div style="z-index:9999;position:fixed;bottom:75px;right:10px;background:#eef;border:1px solid #ccd;padding:0.5rem;font-family:monospace;font-size:0.8rem;border-radius:4px;">
<div class="htmx-active">
⚡ HTMX Active
<br/>
📃
Expand Down
110 changes: 92 additions & 18 deletions core/Support/Debugbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class Debugbar
public static function isAjaxRequest(): bool
{
return (
isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'
) || (
isset($_SERVER['HTTP_HX_REQUEST']) &&
isset($_SERVER['HTTP_HX_REQUEST']) &&
$_SERVER['HTTP_HX_REQUEST'] === 'true'
);
}
Expand All @@ -27,7 +27,7 @@ public static function resetForRequest()
{
// Reset query log for this specific request
DB::resetQueryLog();

// Set new start time for this request
if (!defined('REQUEST_START')) {
define('REQUEST_START', microtime(true));
Expand All @@ -36,7 +36,8 @@ public static function resetForRequest()

public static function render()
{
if (!env('APP_DEBUG')) return;
if (!env('APP_DEBUG'))
return;

$endTime = microtime(true);
$startTime = defined('REQUEST_START') ? REQUEST_START : SPROUT_START;
Expand All @@ -45,20 +46,40 @@ public static function render()
$queries = DB::getQueries();
$totalQueryTime = round(array_sum(array_column($queries, 'duration')), 2);

echo "<div style='
font-family: monospace;
background: #1e1e1e;
color: #eee;
padding: 1rem;
font-size: 14px;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
border-top: 2px solid #4caf50;
box-shadow: 0 -2px 5px rgba(0,0,0,0.4);
'>";
echo "<div id='sproutphp-debugbar' style='
font-family: monospace;
background: #1e1e1e;
color: #eee;
padding: 1rem;
font-size: 14px;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
border-top: 2px solid #4caf50;
box-shadow: 0 -2px 5px rgba(0,0,0,0.4);
transition: transform 0.3s cubic-bezier(.4,2,.6,1), opacity 0.2s;
transform: translateY(100%); opacity: 0; display: none;
'>";

// Toggle button
// Top-right of debugbar
// When hidden, show a floating button at bottom right

echo "<button id='sproutphp-debugbar-toggle' style='
position: absolute;
top: 8px;
right: 16px;
background: #222;
color: #eee;
border: 1px solid #444;
border-radius: 4px;
padding: 0.2em 0.7em;
font-size: 13px;
cursor: pointer;
z-index: 10001;
'>Hide</button>";

echo "<strong>🌿 SproutPHP DebugBar</strong> ";
echo " | Method: <span style='color:#6cf'>" . $_SERVER['REQUEST_METHOD'] . "</span>";
Expand Down Expand Up @@ -86,6 +107,26 @@ public static function render()
}

echo "</div>";

// End debugbar div

// Floating show button (initially hidden)
echo "<button id='sproutphp-debugbar-show' style='
display: block;
position: fixed;
bottom: 12px;
right: 18px;
background: #222;
color: #eee;
border: 1px solid #444;
border-radius: 20px;
padding: 0.4em 1.2em;
font-size: 15px;
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
cursor: pointer;
z-index: 10001;
'>Show DebugBar 🍃</button>";

// Inline script to update URI after HTMX navigation
echo "<script>
function updateSproutDebugbarUri() {
Expand All @@ -97,5 +138,38 @@ function updateSproutDebugbarUri() {
updateSproutDebugbarUri();
document.body.addEventListener('htmx:afterSettle', updateSproutDebugbarUri);
</script>";

// Inline script for toggle

echo "<script>
(function() {
var bar = document.getElementById('sproutphp-debugbar');
var toggle = document.getElementById('sproutphp-debugbar-toggle');
var showBtn = document.getElementById('sproutphp-debugbar-show');
if (!bar || !toggle || !showBtn) return;
// By default, showBtn is visible, bar is hidden
showBtn.style.display = 'block';
bar.style.transform = 'translateY(100%)';
bar.style.opacity = '0';
bar.style.display = 'none';

showBtn.addEventListener('click', function() {
bar.style.display = 'block';
setTimeout(function() {
bar.style.transform = 'translateY(0)';
bar.style.opacity = '1';
}, 10);
showBtn.style.display = 'none';
});
toggle.addEventListener('click', function() {
bar.style.transform = 'translateY(100%)';
bar.style.opacity = '0';
setTimeout(function() {
bar.style.display = 'none';
showBtn.style.display = 'block';
}, 300);
});
})();
</script>";
}
}
21 changes: 12 additions & 9 deletions core/View/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public static function init()
{
$viewsPath = __DIR__ . '/../../app/Views';
$loader = new FilesystemLoader($viewsPath);

$twigConfig = config('view.twig', []);

// Configure cache properly
$cacheEnv = $twigConfig['cache'] ?? false;
$cachePath = false; // Default to no cache
Expand All @@ -27,7 +27,7 @@ public static function init()
mkdir($cachePath, 0777, true);
}
}

self::$twig = new Environment($loader, [
'cache' => $cachePath,
'debug' => $twigConfig['debug'] ?? true,
Expand All @@ -43,11 +43,12 @@ public static function init()
// Register helpers for Twig: auto-register all from helpers.php, merge with config('view.twig_helpers') if set.
self::registerExplicitHelpers();
}

/**
* Register helpers for Twig: auto-register all from helpers.php, merge with config('view.twig_helpers') if set.
*/
private static function registerExplicitHelpers() {
private static function registerExplicitHelpers()
{
// 1. Get all user-defined functions (auto-discover from helpers.php and any loaded helpers)
$userFunctions = get_defined_functions()['user'];

Expand All @@ -60,7 +61,9 @@ private static function registerExplicitHelpers() {
// 4. Register each helper if it exists
foreach ($allHelpers as $helper) {
if (function_exists($helper)) {
self::$twig->addFunction(new \Twig\TwigFunction($helper, $helper));
self::$twig->addFunction(new TwigFunction($helper, $helper));
} else {
log_error("[SproutPHP] Warning: Twig helper function '$helper' does not exist and was not registered.");
}
}
}
Expand All @@ -75,13 +78,13 @@ public static function render($template, $data = [], $return = false)
if (Debugbar::isAjaxRequest() && config('app.debug', false)) {
// Reset debugbar for this request
Debugbar::resetForRequest();

// Render the template first
$content = self::$twig->render($template . '.twig', $data);

// Append debugbar to the response
$debugbar = Debugbar::render();

if ($return) {
return $content . $debugbar;
}
Expand Down