-
Cómo funcionan las Mision...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-14-2026, 09:46 PM
» Respuestas: 0
» Vistas: 105 -
V6 Original/Dark/Memes (A...
Foro: Diseños Terminados
Último mensaje por: carlos007r
06-14-2026, 11:08 AM
» Respuestas: 26
» Vistas: 6,357 -
V5
Foro: Diseños Terminados
Último mensaje por: Aeikox
06-13-2026, 12:16 AM
» Respuestas: 8
» Vistas: 1,452 -
Risus 1.3 Actualizado jQu...
Foro: Risus 1.3
Último mensaje por: Tronlar
06-12-2026, 10:45 PM
» Respuestas: 55
» Vistas: 10,672 -
Preguntas Frecuentes y So...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-12-2026, 06:17 PM
» Respuestas: 0
» Vistas: 83 -
Cómo registrar tu comunid...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-12-2026, 05:32 PM
» Respuestas: 0
» Vistas: 62 -
Cómo monetizar tu comunid...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 07:19 PM
» Respuestas: 0
» Vistas: 73 -
Introducción al SEO para ...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 06:58 PM
» Respuestas: 0
» Vistas: 82 -
Guía completa de SEO para...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 06:48 PM
» Respuestas: 0
» Vistas: 95 -
Diccionario de términos b...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 01:41 PM
» Respuestas: 0
» Vistas: 115
- Mensajes del foro:1,957
- Temas del foro:614
- Miembros:1,036
- Último miembro:carlos007r
Para esto deben tener los temas en la carpeta "themes" y Smarty 4.0, ya que utilizaremos la configuración hecha en smarty.config.php
1 - Buscan en inc/class/c.admin.php
/*
getTemas()
*/
function getTemas()
Arriba agregaremos lo siguiente
# Buscamos los temas no instalados
public function temas_no_instalados() {
global $smarty;
# Arreglo de temas sin intalar
$no_instalado = [];
# Esto esta configurado en smarty.config.php
# Primero buscamos en la carpeta themes si hay un theme sin instalar
$themes = opendir( $smarty->template_dir["themes"] );
# Recorremos toda la carpeta de themes
while ($theme = readdir($themes)) {
if($theme != '.' && $theme != '..'):
# Obtenemos el archivo de instalacion
include $smarty->template_dir["themes"] . $theme . "/install.php";
# Ahora comprobamos si esta instalado
if(!db_exec('fetch_assoc', db_exec([__FILE__, __LINE__], "query", "SELECT tid FROM w_temas WHERE t_path = '{$theme}' LIMIT 1"))["tid"]) {
array_push($no_instalado, [
"nombre" => $tema["nombre"],
"path" => $tema["path"],
"copy" => $tema["copy"]
]);
}
endif;
}
return $no_instalado;
}
luego un poco más abajo buscamos
function newTema()
{
global $tsCore;
//
$tema_path = $tsCore->setSecure($_POST['path']);
// ARCHIVO DE INSTALACION
include ("../../themes/" . $tema_path . '/install.php');
//
if (empty($tema))
return 'Revisa que la carpeta del tema sea correcta.';
foreach ($tema as $key => $val)
{
if (empty($val))
return 'El archivo de instalación del tema es incorrecto. Recuerda utilizar temas oficiales.';
else
$temadb[$key] = $tsCore->setSecure($val);
}
// NUEVO
if (db_exec(array(__FILE__, __LINE__), 'query', 'INSERT INTO `w_temas` (`t_name`, `t_url`, `t_path`, `t_copy`) VALUES (\'' .
$tsCore->setSecure($temadb['nombre']) . '\', \'' . $tsCore->setSecure($temadb['url']) .
'\', \'' . $tsCore->setSecure($tema_path) . '\', \'' . $tsCore->setSecure($temadb['copy']) .
'\')'))
return 1;
else
return 'Ocurrió un error durante la instalación. Consulta el foro ofcial de PHPost.';
}
y la reemplazaremos por
public function newTema() {
global $tsCore, $smarty;
# ARCHIVO DE INSTALACION
$method = (isset($_GET["path"])) ? $_GET["path"] : $_POST["path"];
include $smarty->template_dir["themes"] . $tsCore->setSecure($method) . "/install.php";
# Instalando usando directamente el botón de "instalar tema"
$name = $tsCore->setSecure($tema['nombre']);
$path = $tsCore->setSecure($tema['path']);
$url = $tsCore->settings['url'] . '/themes/' . $path;
$copy = $tsCore->setSecure($tema['copy']);
# Si hay un problema en la carpeta
if(empty($tema)) $data["error"] = 'Revisa que la carpeta del tema sea correcta.';
# Instalamos el tema
if(db_exec([__FILE__, __LINE__], "query", "INSERT INTO w_temas (t_name, t_path, t_url, t_copy) VALUES ('{$name}', '{$path}', '{$url}', '{$copy}')")) {
return true;
} else return $data["error"] = 'Ocurrió un error durante la instalación. Consulta el foro ofcial de PHPost.';
}
2 - Ahora buscamos en inc/php/admin.php
} elseif($action == 'temas'){
y debajo pegamos
$tni = $tsAdmin->temas_no_instalados();
un poco más abajo buscan
$smarty->assign("tsTemas",$tsAdmin->getTemas());
y debajo agregan
$smarty->assign("tsNoTemas", count($tni));
más abajo buscan
} elseif($act == 'nuevo'){
// GUARDAR
if(!empty($_POST['path'])) {
$install = $tsAdmin->newTema();
if($install == 1) $tsCore->redirectTo($tsCore->settings['url'].'/admin/temas?save=true');
else $smarty->assign("tsError",$install);
}
}
y debajo agregan
} elseif($act == 'nuevo'){
# Primero buscamos si hay temas sin instalar
$smarty->assign("tsNoInstall", $tni);
# Guardamos
if(!empty($_POST['path']) or !empty($_GET['path'])) {
if($tsAdmin->newTema()) $tsCore->redirectTo($tsCore->settings['url'].'/admin/temas?save=true');
else $smarty->assign("tsError", $install["error"]);
}
}
3 - Ahora vamos a nuestro tema templates/admin_mods/m.admin_temas.tpl y buscamos
<div class="boxy-title">
<h3>Administrar Temas</h3>
</div>y la reemplazamos por
<div class="boxy-title" style="display: flex;justify-content: *****: center;">
<h3>Administrar Temas</h3>
{if $tsNoTemas >= 1}
<span>Hay <b>{$tsNoTemas} tema{if $tsNoTemas > 1}s{/if}</b> sin instalar</span>
{/if}
</div>luego más abajo buscamos
{elseif $tsAct == 'nuevo'}
{if $tsError}<div style="display: block;" class="mensajes error">{$tsError}</div>{/if}
<form action="" method="post" id="admin_form" autocomplete="off">
<label for="ai_path">Nombre de la carpeta donde esta el tema a instalar:<br /><i>{$tsConfig.url}/themes/</i></label> <input type="text" id="ai_path" name="path" size="30" />
<hr />
<label> </label> <input type="submit" value="Instalar tema" class="mBtn btnOk">
</form>
{/if}y lo reemplazamos por
{elseif $tsAct == 'nuevo'}
{if $tsError}<div class="alerts error">{$tsError}</div>{/if}
{if !empty($tsNoInstall)}
<h4 style="margin: 6px 0;">Temas no instalados</h4>
<p class="emptyData">Estos son temas que estan en "<u><i>{$tsConfig.url}/themes/</i></u>", pero no estan instalados en la base</p>
<form method="post" autocomplete="off">
<input type="hidden" name="manual" value="0">
{foreach $tsNoInstall key=i item=t}
<div style="display: flex;justify-content: *****: center;margin-bottom: 10px;">
<div>
<span><b>{$t.nombre}</b></span>
<span style="display: block;"><b>Carpeta</b>: {$t.path}</span>
<span><b>Autor</b>: {$t.copy}</span>
</div>
<div style="display: flex;justify-content: *****: center;">
<a href="{$tsConfig.url}/admin/temas?act=nuevo&path={$t.path}" class="mBtn btnOk">Instalar {$t.nombre}</a>
</div>
</div>
{/foreach}
</form>
{else}
<form action="" method="post" id="admin_form" autocomplete="off">
<input type="hidden" name="manual" value="1">
<label for="ai_path">Nombre de la carpeta donde esta el tema a instalar:<br /><i>{$tsConfig.url}/themes/</i></label>
<input type="text" id="ai_path" name="path" size="30" />
<hr class="separator">
<input type="submit" value="Instalar tema" class="mBtn btnOk">
</form>
{/if}
{/if}Puede ser que el atributo style modifique el css, esto ya es a su gusto.
Ahora pueden agregar los themes e instalar desde un botón, sin tener que estar escribiendo el nombre del tema en el input.
Bueno después de tanto tiempo de haberlo hecho quiero compartírselo, es un gran cambio para el js y así también reducir un poco más de código.
1 - En acciones.js buscamos la función mencionada en el título
function login_ajax(form, connect){
var el = new Array(), params = '';
if (form == 'registro-logueo' || form == 'logueo-form') {
el['nick'] = $('.reg-login .login-panel #nickname');
el['pass'] = $('.reg-login .login-panel #password');
el['error'] = $('.reg-login .login-panel #login_error');
el['cargando'] = $('.reg-login .login-panel #login_cargando');
el['cuerpo'] = $('.reg-login .login-panel .login_cuerpo');
el['button'] = $('.reg-login .login-panel input[type="submit"]');
} else {
el['nick'] = $('#login_box #nickname');
el['pass'] = $('#login_box #password');
el['error'] = $('#login_box #login_error');
el['cargando'] = $('#login_box #login_cargando');
el['cuerpo'] = $('#login_box .login_cuerpo');
el['button'] = $('#login_box input[type="submit"]');
}
if (typeof connect != 'undefined') {
params = 'connect=facebook';
} else {
if (empty($(el['nick']).val())) {
$(el['nick']).focus();
return;
}
if (empty($(el['pass']).val())) {
$(el['pass']).focus();
return;
}
$(el['error']).css('display', 'none');
$(el['cargando']).css('display', 'block');
$(el['button']).attr('disabled', 'disabled').addClass('disabled');
var remember = ($('#rem').is(':checked')) ? 'true' : 'false';
params = 'nick='+encodeURIComponent($(el['nick']).val())+'&pass='+encodeURIComponent($(el['pass']).val())+'&rem='+remember;
if (form == 'logueo-form') {
params += '&facebook=1';
}
}
$('#loading').fadeIn(250);
$.ajax({
type: 'post', url: global_data.url + '/login-user.php', cache: false, data: params,
success: function (h) {
switch(h.charAt(0)){
case '0':
$(el['error']).html(h.substring(3)).show();
$(el['nick']).focus();
$(el['button']).removeAttr('disabled').removeClass('disabled');
break;
case '1':
if (form != 'registro-logueo') {
close_login_box();
}
if (h.substring(3)=='Home') {
location.href='/';
} else if (h.substr(3) == 'Cuenta') {
location.href = '/cuenta/';
} else {
location.reload();
}
$('#loading').fadeOut(350);
break;
case '2':
$(el['cuerpo']).css('text-align', 'center').css('line-height', '150%').html(h.substring(3));
break;
case '3':
open_login_box();
mydialog.class_aux = 'registro';
mydialog.mask_close = false;
mydialog.close_button = true;
mydialog.show(true);
mydialog.title('Ingresar');
mydialog.body('<br /><br />', 305);
mydialog.buttons(false);
mydialog.procesando_inicio('Cargando...', 'Registro');
mydialog.center();
$.ajax({
type: 'POST',
url: global_data.url + '/login-form.php',
data: '',
success: function(h){
mydialog.procesando_fin();
switch(h.charAt(0)){
case '0':
mydialog.alert('Error', h.substring(3));
break;
case '1':
mydialog.body(h.substring(3), 305);
}
mydialog.center();
}
});
}
},
error: function() {
$(el['error']).html(lang['error procesar']).show();
},
complete: function(){
$(el['cargando']).css('display', 'none');
}
});
}y la reemplazaremos por
login_ajax = () => {
if( empty($("#nickname").val()) ) {
$("#nickname").focus();return
}
if( empty($("#password").val()) ) {
$("#password").focus();return
}
// Datos a enviar
let dato = [
'nick=' + encodeURIComponent($("#nickname").val()),
'pass=' + encodeURIComponent($("#password").val()),
'rem=' + $("#rem").is(':checked')
].join("&");
// Imagen de cargando
$(".login_cuerpo").append('<div id="login_cargando"><img src="'+global_data.img+'images/large-loading.gif" width="32" height="32" alt="Iniciando sesion"></div>');
// Envio los datos
$.post(global_data.url + "/login-user.php", dato, response => {
switch (response.charAt(0)) {
case '0':
$("#login_error").html(response.substring(3)).show()
$("#login_cargando").remove()
break;
// Iniciamos sesion
case '1':
setTimeout(() => (response.charAt(0) != '1' ? location.href = response.substring(3) : location.reload()), 1500)
break;
}
})
.fail(() => {
$("#login_error").html('Error al procesar la petición')
$("#login_cargando").remove()
})
}Listo, así de fácil...Puede ser que en el futuro lo mejore más...
Esto es bastante rápido y fácil.
1 - Buscamos en inc/class/c.user.php
function loginUser($username, $password, $remember = FALSE, $redirectTo = NULL){
global $tsCore;
/* ARMAR VARIABLES */
$username = strtolower($username); // ARMAR VARIABLES
$pp_password = md5(md5($password) . $username);
/* CONSULTA */
$pwtype = (db_exec('num_rows', db_exec(array(__FILE__, __LINE__), 'query', 'SHOW COLUMNS FROM u_miembros LIKE \'user_pwtype\'')) == 1) ? 'user_pwtype,' : '';
$query = db_exec(array(__FILE__, __LINE__), 'query', 'SELECT user_id, user_password, ' . $pwtype . ' user_activo, user_baneado FROM u_miembros WHERE LOWER(user_name) = \''.$username.'\' LIMIT 1');
//
$data = db_exec('fetch_assoc', $query);
if(empty($data)) return '0: El usuario no existe.';
//
if($data['user_pwtype']){
$other_passwords = array();
$other_passwords[] = sha1($username . $password); // SMF 1.1.x, SMF 2.0.x
$other_passwords[] = md5($password); // Zinfinal
//
if(in_array($data['user_password'], $other_passwords)){
// UPDATE
db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_miembros SET user_password = \''.$tsCore->setSecure($pp_password).'\', user_pwtype = \'0\' WHERE user_id = '.$data['user_id'].'');
//
$data['user_password'] = $pp_password;
}
}
// CHECAMOS
if($data['user_password'] != $pp_password){
return '0: Tu contraseña es incorrecta.';
} else {
if($data['user_activo'] == 1){
// Actualizamos la session
$this->session->update($data['user_id'], $remember, TRUE);
// Cargamos la información del usuario
$this->loadUser(true);
// COMPROBAMOS SI TENEMOS QUE ASIGNAR MEDALLAS
$this->DarMedalla();
/* REDERIGIR */
if($redirectTo != NULL) $tsCore->redirectTo($redirectTo); // REDIRIGIR
else return TRUE;
} else return '0: Debes activar tu cuenta';
}
}
y la reemplazaremos por
function loginUser($username, $password, $remember = FALSE, $redirectTo = NULL){
global $tsCore;
# Variable
$username = strtolower($username);
# Filtramos si es nombre o email
$filter = (filter_var($username, FILTER_VALIDATE_EMAIL)) ? 'email' : 'name';
# Consultamos
$data = db_exec('fetch_assoc', db_exec(array(__FILE__, __LINE__), 'query', 'SELECT user_id, user_name, user_password, user_activo, user_baneado FROM u_miembros WHERE LOWER(user_'.$filter.') = \''.$username.'\' LIMIT 1'));
# Comprobamos que el usuario exista
if(empty($data)) return '0: El usuario no existe.';
# Comprobamos la contraseña
$user = ($filter === 'email') ? strtolower($data["user_name"]) : $username;
$check_pass = md5(md5($password) . $user);
if($data['user_password'] === $check_pass) {
# Comprobamos que el usuario este activo
if(intval($data['user_activo']) === 1) {
// Actualizamos la session
$this->session->update($data['user_id'], $remember, TRUE);
// Cargamos la información del usuario
$this->loadUser(true);
// COMPROBAMOS SI TENEMOS QUE ASIGNAR MEDALLAS
$this->DarMedalla();
/* REDERIGIR */
if($redirectTo != NULL) $tsCore->redirectTo($redirectTo);
else return TRUE;
} else return '0: Debes activar tu cuenta';
} else return '0: Tu contraseña es incorrecta.';
}
Y así de fácil se puede hacer el cambio.
En esta versión se creará una copia de seguridad, pero una vez que hayas realizado el cambio y quieras volver a editar se sobrescribirá la copia de seguridad por el nuevo contenido.
Básicamente esto es una actualización, pero no requiere que tengas este mod instalado... Ya que se puede hacer instalar cero
1 - Ir a tu-tema/js/admin.js y debajo de todo agregar
/**
* Editar CSS
* Versión 14.02.2022
*/
$(document).ready(() => $("#opciones").on('change', e => $("#mostrarCss").val(e.target.value)))
var editar_css = new function() {
this.editar = () => {
var fileCss = $('input[name=archivo_css]').val();
if(this.verificar_archivo(fileCss)) {
$.post(global_data.url + '/css-editar.php', 'css=' + fileCss, h => {
$("textarea[name=editar_css]").html(h)
.css({
width: '100%',
height: '500px',
resize: 'vertical'
})
$("textarea[name=editar_css], button[name=guardar_css]").show();
})
}
},
this.guardar = () => {
var params = [
'name=' + $('input[name=archivo_css]').val(),
'contenido=' + $('textarea[name=editar_css]').val()
].join('&')
$.post(global_data.url + '/css-guardar.php', params, h => {
mydialog.show();
mydialog.title('Guardado...');
mydialog.body('Los cambios fueron aplicados');
/**
* Si realizaste este cambio Registrate o inicia tu sesión para ver este contenido
mydialog.buttons([
{mostrar:true,texto:'Aceptar',accion:'admincss()',activo:true},
{mostrar:true,texto:'Cancelar',accion:'cerrar',accion:true}
]);
*/
mydialog.buttons(true, true, 'Aceptar', 'admincss()', true, false, true, 'Cancelar', 'close', true, true);
mydialog.center();
})
},
this.verificar_archivo = filename => {
var ext = (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename.toLowerCase()) : '';
if(ext && /^(css)$/.test(ext)) return true;
else return false;
}
}
// Retorna
admincss = () => location.href = global_data.url + '/admin/css'2 - Ir a templates/t.admin.tpl y buscamos
{elseif $tsAction == 'rangos'}
{include file='admin_mods/m.admin_rangos.tpl'}debajo de agregamos
{elseif $tsAction == 'css'}
{include file='admin_mods/m.admin_css.tpl'}3 - Ir a templates/admin_mods/ y crear un archivo llamado m.admin_css.tpl y agregar lo siguiente (Lo pueden adaptar a su theme)
<style>
#opciones {
padding: 2px;
}
#opciones > option {
padding: 2px;
margin-bottom: 4px;
}
</style>
<div class="boxy-title">
<h3>Editar CSS</h3>
</div>
<div id="res" class="boxy-content">
<span class="mensajes error">Seleccione un archivo, si no se encuentra escríbalo!</span>
<div style="display:grid;gap:10px;grid-template-columns: 200px 1fr;">
<div>
<select id="opciones" size="10">
<option value=''>Selecciona un archivo</option>
{foreach $tsListaCSS item=css}
<option value="{$css.file_name}">{$css.name}</option>
{/foreach}
</select>
</div>
<div >
<div style="display: flex;">
<input type="text" name="archivo_css" id="mostrarCss" placeholder="Ej: estilo.css o css/admin.css" size="15"/>
<button class="mBtn btnOk" style="width:120px;margin-left: 10px;" onclick="editar_css.editar(); return false;">Editar</button>
</div>
<textarea name="editar_css" placeholder="El contenido del css se mostrará aquí" style="margin:10px 0;display: none;"></textarea>
<button class="mBtn btnPrimary" onclick="editar_css.guardar(); return false;" name="guardar_css" style="display: none;">Guardar</button>
</div>
</div>
</div>4 - En la misma carpeta buscan m.admin_sidemenu.tpl y buscan
<li id="a_temas"><span class="cat-title"><a href="{$tsConfig.url}/admin/temas">Temas y apariencia</a></span></li>y agregan
<li id="a_rangos"><span class="cat-title"><a href="{$tsConfig.url}/admin/css">Editar CSS</a></span></li>5 - Luego van a inc/php/admin.php y buscan
} elseif($action == 'medals') {
y arriba agregan
# EDITAR CSS
} elseif($action == 'css') {
$smarty->assign('tsListaCSS', $tsAdmin->obtenemos_css());
6 - Después en inc/class/c.admin.php buscan
/*
saveAds()
*/
function saveAds()
y arriba agregan, para que funcione bien, tiene que haber realizado Actualizar a Smarty 4.0
/**
* EDITAR CSS
*/
public function obtenemos_css() {
global $smarty;
# Solo será esta extensión
$ext = 'css';
# Definimos una variable para crear un arreglo
$lista_css = [];
# Ahora buscaremos todos los css existentes
$dir_css = opendir( $smarty->template_dir["tema"] );
# Recorremos todas las carpetas
while ($style = readdir($dir_css)) {
if($style === '.' || $style === '..') continue;
if(is_file($smarty->template_dir["tema"] . $style)) {
preg_match_all('/([a-zA-Z0-9_-]+\.(css))/', $style, $css);
$file_css = $css[1][0];
if($file_css !== NULL) {
array_push($lista_css, [
'name' => ucfirst(substr($file_css, 0, -4)),
'file_name' => $file_css
]);
}
}
if (is_dir($smarty->template_dir["tema"] . $style)) {
if($style === $ext) {
$carpeta_css = opendir( $smarty->template_dir["tema"] . $ext );
while ($style = readdir($carpeta_css)) {
if($style === '.' || $style === '..') continue;
array_push($lista_css, [
'name' => ucfirst(substr($style, 0, -4)),
'file_name' => $style
]);
}
closedir( $carpeta_css );
}
}
}
closedir( $dir_css );
return $lista_css;
}
7 - Por último van a inc/php/ajax y crean un archivo llamado ajax.css.php y pegan esto o descargan este archivo, en caso que no se cree la carpeta "css_backup", deberán crearla manualmente en files/uploads/ y darle los permisos de escritura 0777
<?php if ( ! defined('TS_HEADER')) exit('No se permite el acceso directo al script');
/**
* Controlador AJAX
*
* @name ajax.css.php
* @author Miguel92
*/
/**********************************\
* (VARIABLES POR DEFAULT) *
\*********************************/
// NIVELES DE ACCESO Y PLANTILLAS DE CADA ACCIÓN
$files = [
'css-editar' => ['n' => 2, 'p' => ''],
'css-guardar' => ['n' => 2, 'p' => ''],
];
/**********************************\
* (VARIABLES LOCALES ESTE ARCHIVO) *
\*********************************/
// REDEFINIR VARIABLES
$tsPage = 'ajax/p.css.'.$files[$action]['p'];
$tsLevel = $files[$action]['n'];
$tsAjax = empty($files[$action]['p']) ? 1 : 0;
/**********************************\
* (INSTRUCCIONES DE CODIGO) *
\*********************************/
// DEPENDE EL NIVEL
$tsLevelMsg = $tsCore->setLevel($tsLevel, true);
if($tsLevelMsg != 1) { echo '0: '.$tsLevelMsg; die();}
/**
* Creamos la carpeta "css_backup" para almacenar las copias
*/
$backups = "../../files/uploads/css_backup";
if(!is_dir($backups)) {
mkdir($backups);
chmod($backups, 0777);
}
$myBackUp = $backups . '/$1-backup.css';
switch($action){
case 'css-editar':
$file_css = $tsCore->setSecure($_POST['css'], true);
$notExt = substr($file_css, 0, -4);
if(file_exists($smarty->template_dir["tema"] . $file_css)) {
$css = file_get_contents($smarty->template_dir["tema"] . $file_css);
# Creamos un backup, solo por seguridad
file_put_contents(str_replace('$1', $notExt, $myBackUp), $css);
echo $css;
} elseif(file_exists($smarty->template_dir["css"] . $file_css)) {
$css = file_get_contents($smarty->template_dir["css"] . $file_css);
# Creamos un backup, solo por seguridad
file_put_contents(str_replace('$1', $notExt, $myBackUp), $css);
echo $css;
} else echo 'Error: el archivo no existe';
break;
case 'css-guardar':
$nombre = $tsCore->setSecure($_POST["name"]);
$contenido = $_POST['contenido'];
$contenido = str_replace(
['\\n', "'", '"'],
['\n', "'", '"'],
$contenido
);
$dir = (file_exists($smarty->template_dir["tema"] . $nombre)) ? "tema" : "css";
$css = $smarty->template_dir[$dir] . $nombre;
file_put_contents($css, $contenido);
break;
}
y eso sería todo, espero no haberme olvidado de algún paso.
(A partir del punto 4 es válido también para smarty 3)
1 - Deben descargar la última versión de smarty del repositorio en github.
2 - Luego van a inc/smarty y eliminan todo el contenido (Aviso, si tienen archivos agregados en plugins les recomiendo hacer una copia)
3 - Abren el archivo descargado "smarty-master.zip", acceden a la carpeta que contiene y luego buscan la carpeta "libs" y extraen el contenido dentro de "inc/smarty"
4 - Ahora vamos a la raíz de nuestro sitio y abrimos "header.php" y sigan los siguientes pasos:
A Buscan
define('TS_FILES', TS_ROOT.'/files/');
y debajo agregamos
define('TS_SMARTY', TS_ROOT.'/inc/smarty/');
B Arriba de "include 'config.inc.php';" agregan
# Definimos donde estan los temas
define('TS_THEMES', TS_ROOT . '/themes/');
# Definimos donde se estan los plugins adicionales
define('TS_PLUGINS', TS_EXTRA . 'plugins/');
# Tiempo de vida del cache antes de ser eliminado [5hs] (3600 equivale 1hs)
define('CACHE_LIFE_TIME', 3600 * 5);
define('CACHE_CHECKED', TRUE);
# Solo usar las carpetas agregadas en $smarty->setTemplateDir()
define('SECURITY', TRUE);
# Para comprimir el html y que sea más rápido
define('COMPRESS_HTML', FALSE);
C En inc/ext crean una carpeta llamada plugins y descargar plugins.zip y la descomprimen en "inc/ext"
Contenido del comprimido zip: fecha, getUrl, hace, kmg, nl2br, quot, rtrim, seo, strlen, trim y ucfirst
D Un poco más abajo buscamos y lo borramos
// Smarty
include TS_CLASS.'c.smarty.php';
E Más abajo buscamos
// Smarty
$smarty = new tsSmarty();
y reemplazamos por
# Todas las instrucciones de smarty comienzan
include TS_ROOT . "/inc/smarty.config.php";
F Al no existir el archivo "smarty.config.php" lo crean dentro de "inc"
5 - Ahora buscamos "/inc/smarty.config.php" y empezaremos la configuración.
A - Abrimos la etiqueta de <?php y luego agregan estas instrucciones
6 - Ahora vamos a la raíz de nuestro sitio y abrimos "footer.php":
A - Borramos todo el contenido del archivo y la reemplazaremos con esto
PD: Se me olvido mencionar que deben ir a inc/php/ajax_files.php y borrar lo siguiente, ya que no lo usaremos
$smarty->template_ts = false; // SMARTY SETTINGS
NOTA:
Como verán en el array $_ACCESO_TPL_PHP_ = [...items...], es el acceso a esas carpetas. ¿Por que incluí esto?, fácil es para simplificar más, antes para incluir un archivo se tenía que agregar de la siguiente manera
{include file='sections/main_header.tpl'}
pero como en este ejemplo, al estar la ruta de la carpeta "sections" en el array se puede usar así
{include file='main_header.tpl'}
sin tener que hacer referencia a la carpeta a la que se tenga que acceder, también se puede usar de la forma corta
{include 'main_header.tpl'}
En la parte que accede al tema, css, js e images es para el funcionamiento de los plugins que había realizado, si desean lo pueden borrar... A no ser que quieran el plugin al que llame phpost, ¿Cuál es su función?: Es agregar todos los css, js sin tener que escribir toda la ruta
para acceder a dicho archivo y en caso de que este archivo no exista, no agregará nada(no va a ser una linea vacía)
este sería un ejemplo:
Agregará la fuente "Roboto" desde google y los estilos que estén mencionados en los parámetros
y lo que que sería cache es como esto "archivo.css?{$smarty.now}", así cuando se hace un cambio
lo apliquen los cambios
{phpost fonts=["Roboto"]
css=[
"tema" => ["estilo.css", "css" => ["live.css", "wysibb.css", "$tsPage.css"]],
"cache" => true
]
... ETC ...
}
Al tener la carpeta plugins dentro de inc/ext, puedes agregar más sin problemas
Bueno hace tiempo hice este cambio para el modal, el cual facilitaría la creaciones de modales con botones.
Antes se tenia que usar así:
mydialog.buttons(true, true, 'SI', "bloquear('"+user+"', true, '"+lugar+"', true)", true, false, true, 'NO', 'close', true, true); Ahora es poco más largo, pero más fácil de entender
mydialog.buttons([
{mostrar:true,texto:'SI',accion:"bloquear('"+user+"', true, '"+lugar+"', true)",activo:true},
{mostrar:true,texto:'NO',accion:'cerrar',activo:true}
]) Tiene varias maneras de poder emplearlo, la primera es como se muestra en el código de arriba ↑ y las otras 2 son de estas formas:
mydialog.buttons({mostrar:true,texto:'SI',accion:"bloquear('"+user+"', true, '"+lugar+"', true)",activo:true})mydialog.buttons(false) // Puede ser trueVamos al archivo acciones.js, buscamos
buttons: function(display_all, btn1_display, btn1_val, btn1_action, btn1_enabled, btn1_focus, btn2_display, btn2_val, btn2_action, btn2_enabled, btn2_focus){
... TODO EL CODIGO INCLUIDO ...
},La reemplazamos por
buttons: function(object) {
let agregar_botones = '';
// Es un objeto...
if(typeof object === 'object') {
// Es un Arreglo (array)...
if(Array.isArray(object)) {
for(let i = 0; i < object.length; i++) {
if(object.mostrar) {
let clase = !empty(object.clase) ? object.clase : (!i ? 'btnOk' : 'btnCancel');
let activo = object.activo ? '' : ' disabled'
// Si la acción es igual a "cerrar"
let accion = (object.accion == 'cerrar') ? ` onclick="mydialog.close()"` : ` onclick="${object.accion}"`
agregar_botones += `<input type="button" class="mBtn ${clase}${activo}" style="display:inline-block" value="${object.texto}"${accion}${activo} >`;
}
}
} else {
if(object.mostrar) {
let clase = !empty(object.clase) ? object.clase : 'btnOk';
let activo = object.activo ? '' : ' disabled'
// Si la acción es igual a "cerrar" o contiene una función
let accion = (object.accion == 'cerrar') ? `onclick="mydialog.close()"` : ` onclick="${object.accion}"`
agregar_botones += `<input type="button" class="mBtn ${clase}${activo}" style="display:inline-block" value="${object.texto}"${accion}${activo}>`;
}
}
// Si el boolean es TRUE entonces mostrará este botón por defecto, si es FALSE no mostrará nada
} else if(typeof object === 'boolean') {
agregar_botones += object ? `<input type="button" class="mBtn btnOk" style="display:inline-block" value="Aceptar" onclick="mydialog.close()">` : ''
}
$('#mydialog #buttons').html(agregar_botones)
}, El objeto que se puede pasar, si solo contendrá un botón pude ir solo el objeto, en caso que sean 2 o más botones deberá ir así
[
{ ... PARAMETROS DEL OBJETO 1 ... },
{ ... PARAMETROS DEL OBJETO 2 ... }
]Los parámetros que se pueden usar
{
mostrar: boolean, // TRUE o FALSE
texto: string, // El texto que se mostrará
accion: string, // Función que se empleará o "cerrar"
activo: boolean, // TRUE o FALSE
clase: string // Opcional, puede incluir clase para modificar la apariencia del botón
} Espero que sea clara la explicación y lo puedan entender...
Hola, esta es otra sugerencia.
Tanto en inc/class/c.core.php como en inc/smarty/plugins/modifier.seo.php, para reemplazar en el plugin solo deben toma lo que esta dentro de la funcion setSEO() y usarlo
Función original:
function setSEO($string, $max = false) {
// ESPAÑOL
$espanol = array('á','é','í','ó','ú','ñ');
$ingles = array('a','e','i','o','u','n');
// MINUS
$string = str_replace($espanol,$ingles,$string);
$string = trim($string);
$string = trim(preg_replace('/[^ A-Za-z0-9_]/', '-', $string));
$string = preg_replace('/[ \t\n\r]+/', '-', $string);
$string = str_replace(' ', '-', $string);
$string = preg_replace('/[ -]+/', '-', $string);
//
if($max) {
$string = str_replace('-','',$string);
$string = strtolower($string);
}
//
return $string;
}
Se puede reducir de esta manera:
function setSEO(string $string = '', bool $max = false) {
// Reemplazar letras con acentos por sus contrapartes sin acentos
$string = str_replace(['á', 'é', 'í', 'ó', 'ú', 'ñ'], ['a', 'e', 'i', 'o', 'u', 'n'], $string);
// Eliminar espacio en blanco al principio y al final y reemplazar otros espacios en blanco con guiones
$string = preg_replace('/\s+/u', '-', trim($string));
// Eliminar cualquier carácter que no sea una letra, dígito o subrayado
$string = preg_replace('/[^\pL\d_-]/u', '', $string);
// Convertir la cadena resultante a minúsculas
$string = mb_strtolower($string);
// Eliminar guiones si se especifica
if ($max) $string = str_replace('-', '', $string);
return $string;
}
Para el plugin modifier.seo.php deben borrar estas líneas, ya que como parámetro solo pasa el texto
// Eliminar guiones si se especifica
if ($max) $string = str_replace('-', '', $string);
ACLARACIÓN: Obviamente al ser para "seo" siempre estará en minúsculas!
Hola, esto es solo una sugerencia, sobre el generador de tags al momento de crear los posts.
Archivo inc/php/c.posts.php
Originalmente viene así:
public function genTags($q){
$content = trim(preg_replace("/[^ A-Za-z0-9]/", "", $q));
$ketxt = preg_replace('/ {2,}/si', " ", $content);
$t = explode(" ", $ketxt);
$total = count($t);
$tg = "";
$i = 0;
foreach($t as $v){ $i++;
$coma = ($i < $total) ? ", " : " ";
$tg .= (strlen($v) >= 4 && strlen($v) <= 8) ? ($v.$coma) : "";
}
$tag = strtolower($tg);
//
return ($tag);
}
Y la forma diferente puede ser de esta manera, es bastante corto y simple
public function genTags(string $q = '') {
$texto = preg_replace('/ {2,}/si', " ", trim(preg_replace("/[^ A-Za-z0-9]/", "", $q)));
$array = []; # Para iniciar el arreglo
# Solo agregamos de más de 4 y menos de 12 letras
foreach (explode(' ', $texto) as $tag):
if(strlen($tag) >= 4 AND strlen($tag) <= 12) {
# Añadimos cada palabra al array
array_push($array, strtolower($tag));
}
endforeach;
return join(', ', $array);
}
Listo, hace exactamente lo mismo!
Hola saludos
Tengo unas preguntas o dudas sobre la tabla w_visitas
¿Es necesaria, para que funcione el script?
¿Qué pasa si la elimino?
¿Si borro los datos de la tabla deja de funcionar el script?
Capturas
Tutorial de instalación en el archivo de la descarga.
Descarga
Mega
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
Mediafire
http://Registrate o inicia tu sesión par... contenido
Uptobox
http://Registrate o inicia tu sesión par... contenido
4shared
http://Registrate o inicia tu sesión par... contenido

