Skip to content

Commit

Permalink
1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
iceman-fx authored Feb 8, 2024
1 parent 8b8a075 commit 543a25d
Show file tree
Hide file tree
Showing 23 changed files with 2,656 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Articletemplates
================

Changelog
---------
<b>Version 1.0</b>
- erste Version mit allen grundlegenden Funktionen
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Articletemplates
================

Redaxo 5-Addon zum Hinzufügen vordefinierter Artikelvorlagen (CMS-Artikel mit angelegten Modulblöcken) in leere Artikel.

Die Vorlagenartikel werden dabei als normale CMS-Artikel mit den gewünschten Modulblöcken und -inhalten angelegt und anschließend als Inhaltsvorlagen bei leeren Artikeln zur Auswahl bereitgestellt.


Features
--------

- Definition der gewünschten Artikelvorlagen mit oder ohne Vorschaubild
- Auswahl der Vorlagen als Blöcke mit Bild oder als reine Textliste
- Optionale Nutzung der Artikelnamen als Titel/Bezeichnung der jeweiligen Vorlage
- Darkmode

-----

### Changelog
siehe CHANGELOG.md des AddOns
Binary file added assets/indicator.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/noimage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions assets/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// articletemplates
// v1.0

$(function(){
let $at_btn, $at_dst, $at_dst_inner, $at_dst_hdr, $at_dst_cnt, $at_dst_olay, $at_url = '';

$(document).on('rex:ready', function(){ initArtTmpl(); });
initArtTmpl();


function initArtTmpl()
{ //console.log("initArtTmpl");

$at_btn = $('#arttmpl-button');
$at_dst = $('#arttmpl-selector');
$at_dst_inner = $at_dst.find('.arttmpl-inner');
$at_dst_hdr = $at_dst.find('.arttmpl-header');
$at_dst_cnt = $at_dst.find('.arttmpl-content');
$at_dst_olay = $at_dst.find('.arttmpl-overlay');
$at_url = '';

hideArtTmplSelector();
$at_btn.on('click', function(e){
e.preventDefault();

//console.log("btn clicked");

btn = $(this).find('button'); btn.blur();
aid = parseInt(btn.data('artid'));
clid = parseInt(btn.data('clid'));
ctype = parseInt(btn.data('ctype'));
$at_url = 'index.php?page=structure&rex-api-call=arttmpl_loadTemplates&aid='+aid+'&clid='+clid+'&ctype='+ctype;

showArtTmplSelector(aid, clid, ctype);
});
$at_dst.find('.arttmpl-overlay, .arttmpl-close').click(function() { hideArtTmplSelector(); });


//max Höhe des Contentbereich setzen
resizeArtTmpl();
$(window).on('load resize', function(e){ resizeArtTmpl(); });


//Suche anbinden
$at_dst_hdr.find('input').keyup(function(){
sbeg = encodeURIComponent($(this).val());
$.post($at_url+'&sbeg='+sbeg, function(data){ $at_dst_cnt.html(data); });
});
}

function resizeArtTmpl()
{ //Auswahlfenster anpassen
tmp = $at_dst_hdr.outerHeight() + 'px';
//workaround für Höhe von unsichtbaren Elementen
if (!$('body').hasClass('arttmpl-active')) {
$at_dst.css({ 'display': 'block', 'visibility': 'hidden', 'position': 'absolute' });
$at_dst_inner.css({ 'display': 'block' });
tmp = $at_dst_hdr.outerHeight() + 'px';
$at_dst_inner.css({ 'display': 'none' });
$at_dst.css({ 'display': 'none', 'visibility': 'visible', 'position': 'fixed' });
}

pd = parseInt($at_dst.css('padding-top')) + parseInt($at_dst.css('padding-bottom'));
$at_dst_cnt.css({ 'max-height': 'calc(100vh - '+pd+'px - '+tmp+')' });
}

function showArtTmplSelector(aid=0, clid=0, ctype=0)
{ //Vorlagen zur Auswahl einladen
if ($at_dst_cnt) {
$.ajax({
//url: 'index.php?page=structure&rex-api-call=arttmpl_loadTemplates&aid='+aid+'&clid='+clid+'&ctype='+ctype
url: $at_url
}).done(function(data) {
//Rückhabe in DOM einbetten
$at_dst_cnt.html(data);

//Auswahlpopup einblenden
$('body').addClass('arttmpl-active');
$at_dst.show();
$at_dst_olay.fadeIn();
setTimeout(function(){ $at_dst_inner.fadeIn(function(){ $at_dst_hdr.find('input').focus(); } ); }, 100);

}).always(function() {
$('#rex-js-ajax-loader').removeClass('rex-visible');
}).fail(function() {})
}
}

function hideArtTmplSelector()
{ //Auswahlpopup ausblenden und leeren
$at_dst_inner.fadeOut();
setTimeout(function(){ $at_dst_olay.fadeOut(function(){
$at_dst.hide();
$('body').removeClass('arttmpl-active');
$at_dst.find('.inner').html('');
}); }, 100);
}

});
43 changes: 43 additions & 0 deletions assets/style-darkmode.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@charset "utf-8";
/* CSS Document for articletemplates - DarkMode */
/* v1.0 */

body.rex-theme-dark #arttmpl-button .btn-default { background-color: #1867a6; border-color: #1867a6; color: rgba(255,255,255, 0.75); }

body.rex-theme-dark #arttmpl-selector .arttmpl-content { background-color: #202b35; }
body.rex-theme-dark #arttmpl-selector .arttmpl-header, body.rex-theme-dark #arttmpl-selector .arttmpl-item.arttmpl-cat { background-color: #1f3d3c !important; color: rgba(255, 255, 255, 0.75) !important; }

body.rex-theme-dark #arttmpl-selector input { color: rgba(255,255,255, 0.75); background-color: rgba(27,35,44, 0.8); border-color: rgba(21,28,34, 0.8); }
body.rex-theme-dark #arttmpl-selector .arttmpl-close button { color: rgba(255,255,255, 0.75); }
body.rex-theme-dark #arttmpl-selector .arttmpl-cat-desc { color: rgba(255,255,255, 0.5); }

body.rex-theme-dark #arttmpl-selector .arttmpl-item { border-color: #1c4260; }
body.rex-theme-dark #arttmpl-selector .arttmpl-item-header { background-color: #213c51; color: rgba(255,255,255, 0.75); }
body.rex-theme-dark #arttmpl-selector .arttmpl-item:hover .arttmpl-item-header { background-color: #1c4260; }
body.rex-theme-dark #arttmpl-selector .arttmpl-item-desc { background: rgba(33,60,81, 0.85); color: rgba(255,255,255, 0.75); }

body.rex-theme-dark #arttmpl-selector .arttmpl-mode-list .arttmpl-item, body.rex-theme-dark #arttmpl-selector .arttmpl-item-header, body.rex-theme-dark #arttmpl-selector .arttmpl-mode-list .arttmpl-item-desc { color: rgba(255,255,255, 0.75); }
body.rex-theme-dark #arttmpl-selector .arttmpl-mode-list .arttmpl-item { background-color: #213c51; border-color: #213c51; }
body.rex-theme-dark #arttmpl-selector .arttmpl-mode-list .arttmpl-item:hover { background-color: #1c4260; border-color: #1c4260; }



@media (prefers-color-scheme: dark){
body:not(.rex-theme-light) #arttmpl-button .btn-default { background-color: #1867a6; border-color: #1867a6; color: rgba(255,255,255, 0.75); }

body:not(.rex-theme-light) #arttmpl-selector .arttmpl-content { background-color: #202b35; }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-header, body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item.arttmpl-cat { background-color: #1f3d3c !important; color: rgba(255, 255, 255, 0.75) !important; }

body:not(.rex-theme-light) #arttmpl-selector input { color: rgba(255,255,255, 0.75); background-color: rgba(27,35,44, 0.8); border-color: rgba(21,28,34, 0.8); }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-close button { color: rgba(255,255,255, 0.75); }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-cat-desc { color: rgba(255,255,255, 0.5); }

body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item { border-color: #1c4260; }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item-header { background-color: #213c51; color: rgba(255,255,255, 0.75); }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item:hover .arttmpl-item-header { background-color: #1c4260; }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item-desc { background: rgba(33,60,81, 0.85); color: rgba(255,255,255, 0.75); }

body:not(.rex-theme-light) #arttmpl-selector .arttmpl-mode-list .arttmpl-item, body:not(.rex-theme-light) #arttmpl-selector .arttmpl-item-header, body:not(.rex-theme-light) #arttmpl-selector .arttmpl-mode-list .arttmpl-item-desc { color: rgba(255,255,255, 0.75); }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-mode-list .arttmpl-item { background-color: #213c51; border-color: #213c51; }
body:not(.rex-theme-light) #arttmpl-selector .arttmpl-mode-list .arttmpl-item:hover { background-color: #1c4260; border-color: #1c4260; }
}
70 changes: 70 additions & 0 deletions assets/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@charset "utf-8";
/* CSS Document for articletemplates */
/* v1.0 */

#arttmpl-button { margin-bottom: 22px; }
#arttmpl-button .btn-default { background: #4b9ad9; border-color: #4b9ad9; color: #FFF; }

body.arttmpl-active { overflow: hidden !important; }

#arttmpl-selector { display: none; position: fixed; width: 100%; height: 100%; left: 0px; top: 0px; padding: 40px; overflow: hidden; z-index: 9999999; transition: all .3s ease; }
#arttmpl-selector .arttmpl-overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(40,53,66, 0.4); z-index: 5; }
#arttmpl-selector .arttmpl-close { position: absolute; top: 3px; right: 9px; }
#arttmpl-selector .arttmpl-close button { float: none; color: #FFF; font-weight: bold; opacity: 1; }

#arttmpl-selector .arttmpl-loading { text-align: center; padding: 10vh; font-weight: bold; }

#arttmpl-selector .arttmpl-inner { position: relative; top: 0px; z-index: 10; width: 100%; max-width: 1600px; margin: auto; padding: 0px; overflow: hidden; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); }
#arttmpl-selector .arttmpl-inner > * { position: relative; width: 100%; max-width: 1600px; padding: 20px 20px; margin: 0px auto; overflow: hidden; }
#arttmpl-selector .arttmpl-header { background: #4b9ad9; color: #FFF; font-weight: bold; }
#arttmpl-selector .arttmpl-content { background: #f8f9fa; overflow: auto; height: auto; max-height: calc(100vh - 80px); }

#arttmpl-selector input { width: 100%; height: 50px; font-weight: normal; background: #dbedf7; margin: 20px 0px 0px; color: #4b9ad9; font-weight: bold; }

#arttmpl-selector .arttmpl-list { display: flex; flex-wrap: wrap; list-style: none; margin: 0px -15px; padding: 0px; }

#arttmpl-selector .arttmpl-item { flex: 0 1 calc(100% - 30px); margin: 0px 15px 30px; padding: 0px; border: 1px solid #e4e4e4; overflow: hidden; transition: all .3s ease; }
#arttmpl-selector .arttmpl-item:hover { box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; }
#arttmpl-selector .arttmpl-item a { display: block; height: 100%; position: relative; color: #324050; text-decoration: none; }
#arttmpl-selector .arttmpl-item-image { width: 100%; aspect-ratio: 3/2; }
#arttmpl-selector .arttmpl-images-pt .arttmpl-item-image { aspect-ratio: 2/3; }
#arttmpl-selector .arttmpl-item img { object-fit: cover; object-position: center top; width: 100%; height: 100%; }
#arttmpl-selector .arttmpl-item-header { position: relative; z-index: 5; display: flex; align-items: center; background: #FFF; text-align: left; font-weight: bold; padding: 10px 15px; line-height: 1.3; min-height: 60px; hyphens: auto; }
#arttmpl-selector .arttmpl-item-desc { position: absolute; left: 0px; bottom: 0px; width: 100%; height: auto; z-index: 5; background: rgba(0,0,0, 0.55); color: #FFF; padding: 10px 15px; font-size: 0.9em; line-height: 1.1; max-height: 50%; overflow: hidden; transition: all .3s ease; }
#arttmpl-selector .arttmpl-item:hover .arttmpl-item-desc { opacity: 0; }

#arttmpl-selector .arttmpl-item.arttmpl-cat { flex-basis: calc(100% - 30px) !important; background: #dbedf7 !important; color: #4b9ad9 !important; padding: 10px 20px !important; font-size: 1.6rem; margin-top: 30px; margin-bottom: 20px !important; border: none; }
#arttmpl-selector .arttmpl-cat:first-child { margin-top: 0px; }
#arttmpl-selector .arttmpl-item.arttmpl-cat:hover { box-shadow: none; }
#arttmpl-selector .arttmpl-cat-header { font-weight: bold; }
#arttmpl-selector .arttmpl-cat-desc { font-size: 0.9em; color: #777; }

/* List-Mode */
#arttmpl-selector .arttmpl-mode-list .arttmpl-item { flex-basis: calc(100% - 30px); margin-bottom: 15px; padding: 10px 20px; background: #FFF; }
#arttmpl-selector .arttmpl-mode-list .arttmpl-item-image { display: none; }
#arttmpl-selector .arttmpl-mode-list .arttmpl-item-header { padding: 5px 0px; min-height: 0px; background: none; }
#arttmpl-selector .arttmpl-mode-list .arttmpl-item-desc { position: relative; left: auto; bottom: auto; z-index: 10; opacity: 1 !important; background: none; color: inherit; padding: 5px 0px; }
#arttmpl-selector .arttmpl-mode-list .arttmpl-item-header + .arttmpl-item-desc { padding-top: 0px; }

#arttmpl-selector .arttmpl-mode-list .arttmpl-item.arttmpl-cat { margin-top: 45px; }



@media (min-width: 600px){
#arttmpl-selector .arttmpl-images-pt .arttmpl-item { flex: 0 1 calc(50% - 30px); }
}
@media (max-width: 680px){
#arttmpl-selector { padding: 20px; }
}
@media (min-width: 680px){
#arttmpl-selector .arttmpl-item { flex: 0 1 calc(50% - 30px); }
}
@media (min-width: 880px){
#arttmpl-selector .arttmpl-images-pt .arttmpl-item { flex: 0 1 calc(33.33% - 30px); }
}
@media (min-width: 1000px){
#arttmpl-selector .arttmpl-item { flex: 0 1 calc(33.33% - 30px); }
}
@media (min-width: 1200px){
#arttmpl-selector .arttmpl-images-pt .arttmpl-item { flex: 0 1 calc(25% - 30px); }
}
99 changes: 99 additions & 0 deletions boot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
/*
Redaxo-Addon Articletemplates
Boot (weitere Konfigurationen & Einbindung)
v1.0
by Falko Müller @ 2024
*/

/** RexStan: Vars vom Check ausschließen */
/** @var rex_addon $this */


//Variablen deklarieren
$mypage = $this->getProperty('package');


//Userrechte prüfen
$isAdmin = ( is_object(rex::getUser()) AND (rex::getUser()->hasPerm($mypage.'[admin]') OR rex::getUser()->isAdmin()) ) ? true : false;


//Addon Einstellungen
$config = $this->getConfig('config'); //Addon-Konfig einladen


//Funktionen einladen/definieren
//Global für Backend+Frontend
global $a1826_mypage;
$a1826_mypage = $mypage;

global $a1826_darkmode;
$a1826_darkmode = (rex_string::versionCompare(rex::getVersion(), '5.13.0-dev', '>=')) ? true : false;


//Backend
if (rex::isBackend()):
require_once(rex_path::addon($mypage, "functions/functions_be.inc.php"));

if (rex::getUser()):

//AJAX anbinden
$ajaxPages = array('load-defaultlist', 'load-catlist');
if (rex_be_controller::getCurrentPagePart(1) == $mypage && in_array(rex_request('subpage', 'string'), $ajaxPages)):
rex_extension::register('OUTPUT_FILTER', 'arttmpl_helper::bindAjax');
endif;


//BE-Templateauswahl einbinden
rex_extension::register('OUTPUT_FILTER', 'arttmpl::addTemplateSelector');

rex_extension::register('STRUCTURE_CONTENT_MODULE_SELECT', function(rex_extension_point $ep){
arttmpl::addTemplateButton($ep);
}, rex_extension::LATE);


//Template in neuen Aertikel kopieren
$artid = rex_request::get('article_id', 'int', null);
$clid = rex_request::get('clang', 'int', null);
$arttmpl_sid = rex_request::get('arttmpl_sid', 'int', null);
$page = arttmpl_helper::textOnly(rex_request::get('page'));
$action = arttmpl_helper::textOnly(rex_request::get('arttmpl_action'));

if ($action == 'copy' && $page == 'content/edit' && !empty($arttmpl_sid) && !empty($artid) && !empty($clid)):
//prüfen, ob Artikel bereits Inhalte hat
$cts = 0;
$art = rex_article::get($artid);
if ($art):
$art_cts = rex_ctype::forTemplate($art->getTemplateId());
$cts = count($art_cts);
endif;
$cts = ($cts < 1) ? 1 : $cts;

$db = rex_sql::factory();
$db->setQuery("SELECT id FROM ".rex::getTable('article_slice')." WHERE article_id = '".$artid."' AND clang_id = '".$clid."' AND ctype_id <= '".$cts."'");

//prüfen, ob Vorlagenartikel existiert
$art = rex_article::get($arttmpl_sid);


if ($art && $db->getRows() <= 0):
rex_content_service::copyContent($arttmpl_sid, $artid, $clid, $clid);
else:
rex_extension::register('STRUCTURE_CONTENT_HEADER', function(rex_extension_point $ep){
echo rex_view::warning(rex_i18n::msg('a1826_error_noarticle_or_notempty'), 'arttmpl-alert-warning');
echo '<script>setTimeout(function() { $("div.arttmpl-alert-warning").fadeOut(); }, 5000)</script>';
});
endif;
endif;

endif;
endif;



// Assets im Backend einbinden (z.B. style.css) - es wird eine Versionsangabe angehängt, damit nach einem neuen Release des Addons die Datei nicht aus dem Browsercache verwendet wird
rex_view::addCssFile($this->getAssetsUrl('style.css'));
if ($a1826_darkmode) { rex_view::addCssFile($this->getAssetsUrl('style-darkmode.css')); }

rex_view::addJsFile($this->getAssetsUrl('script.js'));
?>
46 changes: 46 additions & 0 deletions functions/functions_be.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/*
Redaxo-Addon Articletemplates
Backend-Funktionen (Addon + Modul)
v1.0
by Falko Müller @ 2024
*/

//aktive Session prüfen


//globale Variablen


//Funktionen
//prüft die Bezeichnung auf Vorhandensein
function a1826_duplicateName($str)
{ if (!empty($str)):
$db = rex_sql::factory();
$db->setQuery("SELECT id, title FROM ".rex::getTable('1826_articletemplates')." WHERE title = '".arttmpl_helper::maskSql($str)."'");

if ($db->getRows() > 0):
$str = $str.rex_i18n::msg('a1826_copiedname');
$str = a1826_duplicateName($str);
endif;
endif;

return $str;
}


function a1826_duplicateNameCat($str)
{ if (!empty($str)):
$db = rex_sql::factory();
$db->setQuery("SELECT id, title FROM ".rex::getTable('1826_articletemplates_cat')." WHERE title = '".arttmpl_helper::maskSql($str)."'");

if ($db->getRows() > 0):
$str = $str.rex_i18n::msg('a1826_copiedname');
$str = a1826_duplicateNameCat($str);
endif;
endif;

return $str;
}

?>
Loading

0 comments on commit 543a25d

Please sign in to comment.