Debido al gran cambio entre v2.2 y v2.3, he decidido hacer este tema. Explicando la base de cómo se compone el sistema de Spirate, las plantillas, los sources, las maneras correctas de hacer diferentes acciones.
Comenzemos.
Primero: El sistema de MODs de Spirate es exactamente igual al de SMF. Esto es fundamental, aparte de leerte este tutorial, te podrás leer miles de otros para SMF, que serán igualmente de compatibles en SMF como en Spirate.
En el script hay un archivo y dos carpetas que son
fundamentales.
Uno es el archivo
index.php de la raíz del sitio. Otro la carpeta
Sources, que contiene los archivos que son el "corazón" de Small Pirate. Y por último, la carpeta
Themes, que contiene varias sub-carpetas con los "templates" o "plantillas" de cada theme diferente.
Segundo: Daré una explicación del archivo y carpetas.
index.php: veremos el archivo en sí. La parte más importante de este archivo es esta:
$actionArray = array(
'buddies' => array('Buddies.php', 'BuddiesMain'),
'activate' => array('Register.php', 'Activate'),
'admin' => array('Admin.php', 'Admin'),
'tags' => array('Tags.php', 'TagsMain'),
'ban' => array('ManageBans.php', 'Ban'),
'boardrecount' => array('Admin.php', 'AdminBoardRecount'),
'favoritos' => array('Favoritos.php', 'Favoritos'),
'cleanperms' => array('Admin.php', 'CleanupPermissions'),
'convertentities' => array('Admin.php', 'ConvertEntities'),
'convertutf8' => array('Admin.php', 'ConvertUtf8'),
'coppa' => array('Register.php', 'CoppaForm'),
'contactenos' => array('Contactenos.php', 'ShowHelp'),
'imagenes' => array('Gallery.php', 'GalleryMain'),
'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'),
'detailedversion' => array('Admin.php', 'VersionDetail'),
'display' => array('Display.php', 'Display'),
'dlattach' => array('Display.php', 'Download'),
'dumpdb' => array('DumpDatabase.php', 'DumpDatabase2'),
'extras' => array('Extras.php', 'Extras'),
'featuresettings' => array('ModSettings.php', 'ModifyFeatureSettings'),
'featuresettings2' => array('ModSettings.php', 'ModifyFeatureSettings2'),
'findmember' => array('Subs-Auth.php', 'JSMembers'),
'help' => array('Help.php', 'ShowHelp'),
'helpadmin' => array('Help.php', 'ShowAdminHelp'),
'jsoption' => array('Themes.php', 'SetJavaScript'),
'jsmodify' => array('Post.php', 'JavaScriptModify'),
'terminos-y-condiciones' => array('terminos-y-condiciones.php', 'ShowHelp'),
'widget' => array('widget.php', 'ShowHelp'),
'recomendar' => array('Recomendar.php', 'ShowHelp'),
'cine' => array('Cine.php', 'cine'),
'denunciar' => array('Denunciar.php', 'ShowHelp'),
'enlazanos' => array('Enlazanos.php', 'ShowHelp'),
'gsearch' => array('gsearch.php', 'ShowHelp'),
'protocolo' => array('Protocolo.php', 'ShowHelp'),
'im' => array('PersonalMessage.php', 'MessageMain'),
'jsoption' => array('Themes.php', 'SetJavaScript'),
'jsmodify' => array('Post.php', 'JavaScriptModify'),
'lock' => array('LockTopic.php', 'LockTopic'),
'login' => array('LogInOut.php', 'Login'),
'login2' => array('LogInOut.php', 'Login2'),
'logout' => array('LogInOut.php', 'Logout'),
'maintain' => array('Admin.php', 'Maintenance'),
'manageattachments' => array('ManageAttachments.php', 'ManageAttachments'),
'manageboards' => array('ManageBoards.php', 'ManageBoards'),
'managecalendar' => array('ManageCalendar.php', 'ManageCalendar'),
'managesearch' => array('ManageSearch.php', 'ManageSearch'),
'markasread' => array('Subs-Boards.php', 'MarkRead'),
'membergroups' => array('ManageMembergroups.php', 'ModifyMembergroups'),
'mergetopics' => array('SplitTopics.php', 'MergeTopics'),
'mlist' => array('Memberlist.php', 'Memberlist'),
'modifycat' => array('ManageBoards.php', 'ModifyCat'),
'modifykarma' => array('Karma.php', 'ModifyKarma'),
'hist-mod' => array('Modlog.php', 'ViewModlog'),
'movetopic' => array('MoveTopic.php', 'MoveTopic'),
'movetopic2' => array('MoveTopic.php', 'MoveTopic2'),
'movetopic3' => array('MoveTopic.php', 'MoveTopic3'),
'news' => array('ManageNews.php', 'ManageNews'),
'monitor' => array('Monitor.php', 'Monitor'),
'notify' => array('Notify.php', 'Notify'),
'notifyboard' => array('Notify.php', 'BoardNotify'),
'optimizetables' => array('Admin.php', 'OptimizeTables'),
'packageget' => array('PackageGet.php', 'PackageGet'),
'packages' => array('Packages.php', 'Packages'),
'permissions' => array('ManagePermissions.php', 'ModifyPermissions'),
'pgdownload' => array('PackageGet.php', 'PackageGet'),
'pm' => array('PersonalMessage.php', 'MessageMain'),
'post' => array('Post.php', 'Post'),
'agregar' => array('Agregar.php', 'Agregar'),
'agregar2' => array('Agregar.php', 'Agregar2'),
'post2' => array('Post.php', 'Post2'),
'postsettings' => array('ManagePosts.php', 'ManagePostSettings'),
'printpage' => array('Printpage.php', 'PrintTopic'),
'profile' => array('Profile.php', 'ModifyProfile'),
'profile2' => array('Profile.php', 'ModifyProfile2'),
'quotefast' => array('Post.php', 'QuoteFast'),
'quickmod' => array('Subs-Boards.php', 'QuickModeration'),
'quickmod2' => array('Subs-Boards.php', 'QuickModeration2'),
'index' => array('Recent.php', 'RecentPosts'),
'regcenter' => array('ManageRegistration.php', 'RegCenter'),
'registrarse' => array('Register.php', 'Register'),
'register2' => array('Register.php', 'Register2'),
'reminder' => array('Reminder.php', 'RemindMe'),
'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'),
'removeoldtopics2' => array('RemoveTopic.php', 'RemoveOldTopics2'),
'repairboards' => array('RepairBoards.php', 'RepairBoards'),
'requestmembers' => array('Subs-Auth.php', 'RequestMembers'),
'search' => array('Search.php', 'PlushSearch1'),
'search2' => array('Search.php', 'PlushSearch2'),
'enviar-a-amigo' => array('SendTopic.php', 'SendTopic'),
'serversettings' => array('ManageServer.php', 'ModifySettings'),
'serversettings2' => array('ManageServer.php', 'ModifySettings2'),
'sitemap' => array('Sitemap.php', 'ShowSiteMap'),
'smileys' => array('ManageSmileys.php', 'ManageSmileys'),
'splittopics' => array('SplitTopics.php', 'SplitTopics'),
'TOPs' => array('Stats.php', 'DisplayStats'),
'sticky' => array('LockTopic.php', 'Sticky'),
'rz' => array('Acciones.php', 'Acciones'),
'theme' => array('Themes.php', 'ThemesMain'),
'trackip' => array('Profile.php', 'trackIP'),
'viewErrorLog' => array('ManageErrors.php', 'ViewErrorLog'),
'viewmembers' => array('ManageMembers.php', 'ViewMembers'),
'viewprofile' => array('Profile.php', 'ModifyProfile'),
'verificationcode' => array('Register.php', 'VerificationCode'),
'who' => array('Who.php', 'Who'),
'.xml' => array('News.php', 'ShowXmlFeed'),
'enviar-puntos' => array('shop/Shop.php', 'Shop'),
'shop_general' => array('shop/ShopAdmin.php', 'ShopGeneral'),
'shop_inventory' => array('shop/ShopAdmin.php', 'ShopInventory'),
'shop_items_add' => array('shop/ShopAdmin.php', 'ShopItemsAdd'),
'shop_items_edit' => array('shop/ShopAdmin.php', 'ShopItemsEdit'),
'shop_restock' => array('shop/ShopAdmin.php', 'ShopRestock'),
'shop_usergroup' => array('shop/ShopAdmin.php', 'ShopUserGroup'),
'shop_cat' => array('shop/ShopAdmin.php', 'ShopCategories'),
);
if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']]))
{
if (!empty($settings['catch_action']))
{
require_once($sourcedir . '/Themes.php');
return 'WrapAction';
}
require_once($sourcedir . '/Recent.php');
return 'RecentPosts';
}
require_once($sourcedir . '/' . $actionArray[$_REQUEST['action']][0]);
return $actionArray[$_REQUEST['action']][1];
$actionArray es una variable que contiene
todos los
?action=. Analizaremos los arrays que están dentro del array.
'widget' => array('widget.php', 'ShowHelp'),
Lo que estamos viendo, traducido sería esto:
'ACCION' => array('ARCHIVO.php', 'FUNCION'),Donde ACCION es el ?action, ARCHIVO.php el archivo de la modificación ubicado en la carpeta /Sources y FUNCION es la función principal del MOD, que veremos a continuación cómo se compone un archivo de la carpeta /Sources.
Tercero: analizaremos un archivo Sources, corazón del MOD que haremos para que funcione correctamente.
<?php
if (!defined('SMF'))
die('403 - Peluchin Detected!');
function Pedidos()
{
global $settings, $user_info, $language, $context, $txt;
//Título
$context['page_title'] = 'Pedidos';
//Cargo .template.php
loadTemplate('Pedidos');
//Cargo $txt
loadLanguage('Pedidos');
// ;sa=todos = template_main
$context['all_pages'] = array(
'todos' => 'main',
'pendientes' => 'pendientes',
'cumplidos' => 'cumplidos',
'agregar' => 'agregar',
'cerrar' => 'cerrar',
'borrar' => 'borrar',
);
//Si no se seteo la subaccion, esto te lleva.
if (!isset($_GET['sa']) || !isset($context['all_pages'][$_GET['sa']]))
$_GET['sa'] = 'todos';
$context['current_page'] = $_GET['sa'];
$context['sub_template'] = '' . $context['all_pages'][$context['current_page']];
}
?>
Este Source es del MOD pedidos, que hice. Lo usé de ejemplo porque es muy limpio. Veremos diferentes partes:
<?php
if (!defined('SMF'))
die('403 - Peluchin Detected!');
Se inicia el código PHP, la función
defined() verifica si el sistema es SMF. La función
die() devuelve el valor que encierra si el sistema no es SMF.
function Pedidos()
{
global $settings, $user_info, $language, $context, $txt;
//Título
$context['page_title'] = 'Pedidos';
//Cargo .template.php
loadTemplate('Pedidos');
//Cargo $txt
loadLanguage('Pedidos');
Se inicia la FUNCION, que será la que pondramos en el campo FUNCION del array en el index.php.
global declara variables globales, es decir, es que están en TODO el script SIEMPRE, y no hace falta llamar su valor, etc.
$context['page_title'] será la variable que contenga el título de la página del MOD.
loadTemplate(); llama al archivo que contiene los templates o plantillas. NO se debe agregar el .template.php al nombre, solo el prefijo del archivo.
loadLanguage(); llama al archivo de texto que contiene los $txt, de la misma manera, no se debe agregar el .spanish.php o .english.php, solo el prefijo del archivo, que llamará al idioma correspondiente que esté activado.
// ;sa=todos = template_main
$context['all_pages'] = array(
'todos' => 'main',
'pendientes' => 'pendientes',
'cumplidos' => 'cumplidos',
'agregar' => 'agregar',
'cerrar' => 'cerrar',
'borrar' => 'borrar',
);
$context['all_pages'] serán todas las páginas del MOD. El array contiene primero la subacción, y seguido de "=>" el sufijo del subtemplate (ejemplo,
template_main(){}). El prefijo de todos los subtemplates el SIEMPRE
template_
//Si no se seteo la subaccion, esto te lleva.
if (!isset($_GET['sa']) || !isset($context['all_pages'][$_GET['sa']]))
$_GET['sa'] = 'todos';
$context['current_page'] = $_GET['sa'];
$context['sub_template'] = '' . $context['all_pages'][$context['current_page']];
}
?>
Acá dice que si no se encuentra la subacción que se pide (que es la primer parte del array), llama a
todos, que será
template_main().
$context['current_page'] se declara mediante la variable que se pasa por el navegador
sa=. Y $context['sub_template'] llama al subtemplate por medio de la variable
sa= declarada.
Cuarto: Ahora nos toca la parte de los
templates o plantillas. Analizaremos las del MOD Pedidos.
<?php
function template_main()
{}
function template_pendientes()
{}
function template_cumplidos()
{}
function template_agregar()
{}
function template_cerrar()
{}
function template_borrar()
{}
?>
Bueno, el contenido de las funciones está vacia por cuestiones que sino el post sería muy largo. Pero podemos ver que cada sufijo de las funciones (el prefijo es
template_ y el sufijo lo que viene después), corresponde con la subacción y con el template.
Es decir:
function template_borrar(){}Corresponde con:
'borrar' => 'borrar', //'SUBACCION' => 'SufijoTemplate',Bueno, tuto terminado. Espero que les haya gustado.
Suerte!