1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-06 23:06:59 +02:00

Add $config->versionUrls() method for versioned file URLs and update the admin themes to use it

This commit is contained in:
Ryan Cramer
2023-09-08 11:58:38 -04:00
parent deccd2c8eb
commit 7dc8ddc9af
5 changed files with 117 additions and 12 deletions

View File

@@ -948,10 +948,98 @@ class Config extends WireData {
*/
public function setWire(ProcessWire $wire) {
parent::setWire($wire);
$paths = $this->paths;
if($paths) $paths->setWire($wire);
$urls = $this->urls;
if($urls) $urls->setWire($wire);
foreach(array('paths', 'urls', 'styles', 'scripts') as $key) {
$value = $this->get($key);
if($value instanceof Wire) $value->setWire($wire);
}
}
}
/**
* Given array of file asset URLs return them with cache-busting version strings
*
* URLs that aready have query strings or URLs with scheme (i.e. https://) are ignored.
* URLs that do not resolve to a physical file on the file system, relative URLs, or
* URLs that are outside of ProcessWires web root, are only eligible to receive a
* common/shared version in the URL (like the core version).
*
* ~~~~~
* foreach($config->versionUrls($config->styles) as $url) {
* echo "<link rel='stylesheet' href='$url' />";
* }
* // there is also this shortcut for the above
* foreach($config->styles->urls() as $url) {
* echo "<link rel='stylesheet' href='$url' />";
* }
* ~~~~~
*
* #pw-group-URLs
* #pw-group-tools
*
* @param array|FilenameArray|WireArray|\ArrayObject $urls Array of URLs to file assets such as JS/CSS files.
* @param bool|null|string $useVersion What to use for the version string (`null` is default):
* - `true` (bool): Get version from filemtime.
* - `false` (bool): Never get file version, just use $config->version.
* - `null` (null): Auto-detect: use file version in debug mode or dev branch only, $config->version otherwise.
* - `str` (string): Specify any string to be the version to use on all URLs needing it.
* @return array Array of URLs updated with version strings where needed
* @since 3.0.227
*
*/
public function versionUrls($urls, $useVersion = null) {
$a = array();
$rootUrl = $this->urls->root;
$rootPath = $this->paths->root;
$versionStr = "?v=" . (is_string($useVersion) ? $useVersion : $this->version);
if($useVersion === null) {
$useVersion = ($this->debug || ProcessWire::versionSuffix === 'dev');
}
foreach($urls as $url) {
if(strpos($url, $versionStr)) {
if($useVersion === false) {
$a[] = $url;
continue;
}
list($u, $r) = explode($versionStr, $url, 2);
if(!strlen($r)) $url = $u;
}
if(strpos($url, '?') !== false || strpos($url, '//') !== false) {
$a[] = $url;
} else if($useVersion === true && strpos($url, $rootUrl) === 0) {
$f = $rootPath . substr($url, strlen($rootUrl));
if(is_readable($f)) {
$a[] = "$url?" . base_convert((int) filemtime($f), 10, 36);
} else {
$a[] = $url . $versionStr;
}
} else {
$a[] = $url . $versionStr;
}
}
return $a;
}
/**
* Given a file asset URLs return it with cache-busting version string
*
* URLs that aready have query strings are left alone.
*
* #pw-group-URLs
* #pw-group-tools
*
* @param string $url URL to a file asset (such as JS/CSS file)
* @param bool|null|string $useVersion See versionUrls() method for description of this argument.
* @return string URL updated with version strings where necessary
* @since 3.0.227
* @see Config::versionUrls()
*
*/
public function versionUrl($url, $useVersion = null) {
$a = $this->versionUrls(array($url), $useVersion);
return isset($a[0]) ? $a[0] : $url;
}
}

View File

@@ -10,7 +10,7 @@
*
*/
class FilenameArray implements \IteratorAggregate, \Countable {
class FilenameArray extends Wire implements \IteratorAggregate, \Countable {
/**
* Array of filenames indexed by MD5 hash of filename
@@ -87,6 +87,23 @@ class FilenameArray implements \IteratorAggregate, \Countable {
return new \ArrayObject($this->data);
}
/**
* Get cache-busting URLs for this FilenameArray
*
* This is the same as iterating this FilenameArray except that it appends cache-busting
* query strings to the URLs that resolve to physical files.
*
* @param bool|null|string $useVersion See Config::versionUrls() for arument details
* @return array
* @throws WireException
* @see Config::versionUrls()
* @since 3.0.227
*
*/
public function urls($useVersion = null) {
return $this->wire()->config->versionUrls($this, $useVersion);
}
/**
* Make FilenameArray unique (deprecated)
*

View File

@@ -59,9 +59,9 @@ $extras = $adminTheme->getExtraMarkup();
<script type="text/javascript"><?php echo $helpers->renderJSConfig(); ?></script>
<?php foreach($config->styles as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?>
<?php foreach($config->styles->urls() as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?>
<?php foreach($config->scripts as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?>
<?php foreach($config->scripts->urls() as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?>
<?php echo $extras['head']; ?>

View File

@@ -60,8 +60,8 @@ $extras = $adminTheme->getExtraMarkup();
<title><?php echo $helpers->renderBrowserTitle(); ?></title>
<script type="text/javascript"><?php echo $helpers->renderJSConfig(); ?></script>
<?php foreach($config->styles as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?>
<?php foreach($config->scripts as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?>
<?php foreach($config->styles->urls() as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?>
<?php foreach($config->scripts->urls() as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?>
<?php echo $extras['head']; ?>
</head>

View File

@@ -46,12 +46,12 @@ $scripts->append($themeUrl . "scripts/main.js?v=$version");
</script>
<?php
foreach($styles as $file) {
foreach($styles->urls() as $file) {
echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />";
}
if($adminTheme->maxWidth && strpos($layout, 'sidenav') === false) {
echo "\n\t<style type='text/css'>.pw-container { max-width: {$adminTheme->maxWidth}px; }</style>";
}
foreach($scripts as $file) {
foreach($scripts->urls() as $file) {
echo "\n\t<script type='text/javascript' src='$file'></script>";
}