Add theme settings

Adding simple theme settings. We can add the fields available in theme.json.
This commit is contained in:
danpros 2025-10-29 13:15:20 +07:00
commit c442f92dde
7 changed files with 284 additions and 14 deletions

View file

@ -131,17 +131,6 @@ Please install and enable the INTL extension to format the date format to your l
</div>
</div>
</div>
<div class="form-group row">
<label for="views.root" class="col-sm-2 col-form-label"><?php echo i18n('Blog_Theme');?></label>
<div class="col-sm-10">
<select class="form-control" id="views.root" name="-config-views.root">
<?php foreach (glob('themes/*/layout.html.php') as $folder) { ?>
<?php $theme = explode('/',pathinfo($folder)['dirname']); global $config_file; $this_config = parse_ini_file($config_file, true);?>
<option value="<?php echo pathinfo($folder)['dirname'];?>" <?php if ($this_config['views.root'] === pathinfo($folder)['dirname']):?>selected<?php endif;?>><?php echo $theme['1'];?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group row">
<label for="blog.copyright" class="col-sm-2 col-form-label"><?php echo i18n('Copyright_Line');?></label>
<div class="col-sm-10">

View file

@ -0,0 +1,84 @@
<?php if (!defined('HTMLY')) die('HTMLy'); ?>
<?php
$theme = $theme;
$configPath = 'themes/' . $theme . '/theme.json';
$theme_path = 'themes/' . $theme;
$image = ($m = glob($theme_path . '/screenshot.*')) ? site_url() . $m[0] : site_url() . 'system/resources/images/default-screenshot.jpg';
$themeConfig = array();
if (file_exists($configPath)) {
$json = file_get_contents($configPath);
$themeConfig = json_decode($json, true);
}
?>
<?php if (!empty($themeConfig)): ?>
<div class="row">
<div class="col">
<div class="mb-3">
<img class="card-img-top" style="object-fit: cover;" height="400px" src="<?php echo $image;?>"/>
</div>
</div>
<div class="col">
<div class="mb-3">
<strong>Theme:</strong>
<div><?php echo $themeConfig['name'] ?: $theme; ?></div>
</div>
<div class="mb-3">
<strong>Version:</strong>
<div><?php echo $themeConfig['version'] ?: HTMLY_VERSION; ?></div>
</div>
<div class="mb-3">
<strong>Author:</strong>
<div><?php echo $themeConfig['author'] ?: 'Contributor'; ?></div>
</div>
<div class="mb-3">
<strong>Homepage:</strong>
<div><a target="_blank" href="<?php echo $themeConfig['homepage'] ?: site_url(); ?>"><?php echo $themeConfig['homepage'] ?: site_url(); ?></a></div>
</div>
<div class="mb-3">
<strong>Description:</strong>
<div><?php echo $themeConfig['description'] ?: 'HTMLy ' . $theme; ?></div>
</div>
</div>
</div>
<br><br>
<?php if (!empty($themeConfig['settings'])): ?>
<h2><?php echo i18n('settings');?></h2>
<form method="POST">
<input type="hidden" name="csrf_token" value="<?php echo get_csrf(); ?>">
<?php foreach ($themeConfig['settings'] as $setting):?>
<div class="form-group row">
<label class='col-sm-2 col-form-label'><?php echo $setting['label'];?></label>
<div class="col-sm-10">
<?php if ($setting['type'] === 'select'): ?>
<select class='form-control' name='-config-<?php echo $setting['name'];?>'>
<?php foreach ($setting['options'] as $option):?>
<?php $selected = $option === theme_config($setting['name']) ? 'selected' : '';?>
<option value='<?php echo $option;?>' <?php echo $selected;?>><?php echo $option;?></option>
<?php endforeach;?>
</select>
<?php elseif ($setting['type'] === 'checkbox'): ?>
<?php $checked = theme_config($setting['name']) ? 'checked' : '';?>
<input type="hidden" name="-config-<?php echo $setting['name'];?>" value="0" />
<input type='checkbox' name='-config-<?php echo $setting['name'];?>' <?php echo $checked;?> value="1"/>
<br>
<?php else: ?>
<input class="form-control" type="<?php echo $setting['type'];?>" name="-config-<?php echo $setting['name'];?>" value="<?php echo theme_config($setting['name']);?>"/>
<?php endif;?>
<small><em><?php echo $setting['info'];?></em></small>
</div>
</div>
<?php endforeach;?>
<div class="form-group row">
<div class="col-sm-10 offset-sm-2">
<button type="submit" class="btn btn-primary"><?php echo i18n('Save_Config');?></button>
</div>
</div>
</form>
<?php endif;?>
<?php endif; ?>

View file

@ -0,0 +1,43 @@
<?php if (!defined('HTMLY')) die('HTMLy'); ?>
<?php
global $config_file;
$this_config = parse_ini_file($config_file, true);
?>
<div class="row">
<?php foreach (glob('themes/*/layout.html.php') as $folder) : ?>
<?php $exp = explode('/',pathinfo($folder)['dirname']); $theme = $exp['1']; $theme_path = pathinfo($folder)['dirname'];?>
<?php $image = ($m = glob($theme_path . '/screenshot.*')) ? site_url() . $m[0] : site_url() . 'system/resources/images/default-screenshot.jpg';?>
<div class="col-lg-4 col-md-6">
<div class="card">
<div class="card-header"><img class="card-img-top" height="200px" style="object-fit: cover;" src="<?php echo $image;?>"/></div>
<div class="card-body">
<h1><?php echo $theme;?></h1>
<?php if ($this_config['views.root'] === $theme_path ):?>
<button class="btn btn-secondary disabled"><?php echo i18n('enable');?></button>
<?php else:?>
<button class="btn btn-primary enable-button" data-value="<?php echo $theme_path;?>"><?php echo i18n('enable');?></button>
<?php endif;?>
<?php if ($this_config['views.root'] === $theme_path && file_exists($theme_path . '/theme.json')) :?>
<a class="btn btn-primary" href="<?php echo site_url() . 'admin/themes/' . $theme;?>"><?php echo i18n('settings');?></a>
<?php endif;?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<script>
$('.enable-button').on("click", function(e) {
var data = $(e.target).attr('data-value');
$.ajax({
type: 'POST',
url: '<?php echo site_url();?>admin/themes',
dataType: 'json',
data: {'json': data},
success: function (response) {
alert(response.message);
location.reload();
},
});
});
</script>

View file

@ -22,6 +22,9 @@ if (config('timezone')) {
// Publish scheduled post
publish_scheduled();
// Load theme settings
theme_settings();
// The front page of the blog
get('/index', function () {
@ -3272,6 +3275,107 @@ post('/admin/field/profile', function () {
}
});
// Show admin/themes
get('/admin/themes', function () {
if (login()) {
config('views.root', 'system/admin/views');
render('theme', array(
'title' => generate_title('is_default', i18n('blog_theme')),
'description' => safe_html(strip_tags(blog_description())),
'canonical' => site_url(),
'metatags' => generate_meta(null, null),
'type' => 'is_admin-content',
'is_admin' => true,
'bodyclass' => 'admin-content',
'breadcrumb' => '<a href="' . site_url() . '">' . config('breadcrumb.home') . '</a> &#187; ' . i18n('blog_theme')
));
} else {
$login = site_url() . 'login';
header("location: $login");
}
});
post('/admin/themes', function () {
if (login()) {
$new_config = array();
$new_Keys = array();
$user = $_SESSION[site_url()]['user'];
$role = user('role', $user);
if ($role === 'admin') {
$json = $_REQUEST['json'];
$new_config['views.root'] = $json;
save_config($new_config, $new_Keys);
echo json_encode(array(
'message' => 'Theme activated!',
));
}
}
});
// Show admin/themes/:theme
get('/admin/themes/:theme', function ($theme) {
$exp = explode('/', config('views.root'));
if ($theme !== $exp[1]) {
$redir = site_url() . 'admin/themes';
header("location: $redir");
}
if (login()) {
config('views.root', 'system/admin/views');
render('theme-settings', array(
'title' => generate_title('is_default', $theme),
'description' => safe_html(strip_tags(blog_description())),
'canonical' => site_url(),
'metatags' => generate_meta(null, null),
'type' => 'is_admin-content',
'theme' => $theme,
'is_admin' => true,
'bodyclass' => 'admin-content',
'breadcrumb' => '<a href="' . site_url() . '">' . config('breadcrumb.home') . '</a> &#187; <a href="'. site_url() .'admin/themes">' . i18n('blog_theme') . '</a> &#187; ' . $theme
));
} else {
$login = site_url() . 'login';
header("location: $login");
}
});
// Submitted theme settings data
post('/admin/themes/:theme', function ($theme) {
$exp = explode('/', config('views.root'));
if ($theme !== $exp[1]) {
$redir = site_url() . 'admin/themes';
header("location: $redir");
}
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
if (login() && $proper) {
$new_config = array();
$new_Keys = array();
$user = $_SESSION[site_url()]['user'];
$role = user('role', $user);
if ($role === 'admin') {
foreach ($_POST as $name => $value) {
if (substr($name, 0, 8) == "-config-") {
$name = substr($name, 8);
if(!is_null(theme_config($name))) {
$new_config[$name] = $value;
} else {
$new_Keys[$name] = $value;
}
}
}
save_theme_config($new_config, $new_Keys, $theme);
$redir = site_url() . 'admin/themes/' . $theme;
header("location: $redir");
} else {
$redir = site_url();
header("location: $redir");
}
} else {
$login = site_url() . 'login';
header("location: $login");
}
});
// Show the category page
get('/category/:category', function ($category) {

View file

@ -131,6 +131,56 @@ function save_config($data = array(), $new = array())
return file_put_contents($config_file, $string, LOCK_EX);
}
// Set the theme settings
function theme_settings()
{
$exp = explode('/', config('views.root'));
$settings = 'config/themes/' . $exp[1] . '.ini';
if (file_exists($settings)) {
theme_config('source', $settings);
}
}
function theme_config($key, $value = null)
{
static $_config = array();
if ($key === 'source' && file_exists($value))
$_config = parse_ini_file($value, true);
elseif ($value == null)
return (isset($_config[$key]) ? $_config[$key] : null);
else
$_config[$key] = $value;
}
function save_theme_config($data = array(), $new = array(), $theme = null)
{
$dir = 'config/themes/';
if (!is_dir($dir)) {
mkdir($dir, 0775, true);
}
$config_file = $dir . $theme . '.ini';
$string = file_get_contents($config_file) . "\n";
foreach ($data as $word => $value) {
$value = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$map = array('\r\n' => ' \n ', '\r' => ' \n ');
$value = trim(strtr($value, $map));
$string = preg_replace("/^" . $word . " = .+$/m", $word . ' = ' . $value, $string);
}
$string = rtrim($string);
foreach ($new as $word => $value) {
$value = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$map = array('\r\n' => ' \n ', '\r' => ' \n ');
$value = trim(strtr($value, $map));
$string .= "\n" . $word . ' = ' . $value . "\n";
}
$string = rtrim($string);
return file_put_contents($config_file, $string, LOCK_EX);
}
function get_search_query()
{
if (isset($_GET['search'])) {

View file

@ -2388,9 +2388,9 @@ function shorten($string = null, $char = null)
$string = ltrim(rtrim($string));
$string = str_replace('<span class="dom-charset"><meta charset="utf8"></span>', '', $string);
if (!empty($char)) {
if (strlen($string) > $char) {
$string = substr($string, 0, $char);
$string = substr($string, 0, strrpos($string, ' '));
if (mb_strlen($string) > $char) {
$string = mb_substr($string, 0, $char);
$string = mb_substr($string, 0, mb_strrpos($string, ' '));
}
}
return $string;

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB