فهرست منبع

implements the template selection from module ot_customizer

Olivier Massot 5 سال پیش
والد
کامیت
a9c62d17ff

+ 3 - 2
composer.json

@@ -36,8 +36,9 @@
 		"fluidtypo3/vhs": "^6.0",
 		"georgringer/news": "^8.3",
 		"guzzlehttp/guzzle": "^6",
-		"ext-json": "^1.6"
-	},
+		"ext-json": "^1.6",
+      	"ext-pdo": "*"
+    },
 	"scripts":{
 		"typo3-cms-scripts": [
 			"typo3cms install:fixfolderstructure",

+ 71 - 27
ot_templating/Classes/Controller/OtCustomizerController.php

@@ -3,8 +3,9 @@
 namespace Opentalent\OtTemplating\Controller;
 
 use Opentalent\OtTemplating\Utilities\OtPageRepository;
-use TYPO3\CMS\Core\Page\PageRenderer;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use PDO;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -15,53 +16,96 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class OtCustomizerController extends ActionController {
 
-    CONST themes = [
-        'classic' => [
+    CONST templates = [
+        'Classic' => [
             'name' => 'Classique',
-            'description' => 'Le thème classique',
+            'description' => 'Le thème classique, simple et complet.',
             'picture' => 'EXT:ot_templating/Resources/Public/media/theme_classic.png'
         ],
-        'modern' => [
+        'Modern' => [
             'name' => 'Moderne',
-            'description' => 'Le thème 2020 pour votre site',
+            'description' => '[Nouveau] Un thème moderne et intuitif.',
             'picture' => 'EXT:ot_templating/Resources/Public/media/theme_modern.png'
         ]
     ];
 
-
     /**
-     *
-     * @var int
+     * Index action (default action)
+     * Displays the customize page on the backend
      */
-    protected $pageRootId;
+    public function indexAction() {
+
+        // Get the current root page's uid
+        $rootPageUid = $this->getCurrentRootPageUid();
+
+        // If the current page is not a root page or a subpage of one, abort
+        $pageSelected = ($rootPageUid !== null);
+        $this->view->assign('pageSelected', (int)$pageSelected);
+        if (!$pageSelected) {
+            return;
+        }
 
-    public function __construct() {
-        $this->pageRootId = (int) GeneralUtility::_GP('id');
+        $this->view->assign('rootPage', $rootPageUid);
+        $this->view->assign('templates', self::templates);
     }
 
     /**
-     * Index action
+     * A template has been selected, apply the change
      */
-    public function indexAction() {
+    public function selectTemplateAction() {
+        $templateKey = $this->request->getArgument('template_key');
+
+        // Get the current root page's uid
+        $rootPageUid = $this->getCurrentRootPageUid();
+
+        // applies the change in the database
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
+        $queryBuilder->update('pages')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'uid',
+                    $queryBuilder->createNamedParameter($rootPageUid, PDO::PARAM_INT)
+                )
+            )
+            ->set('tx_opentalent_template', $templateKey)
+            ->execute()
+        ;
+
+        // Clear the page cache
+        $this->cleanCache();
 
-        // Get the current page
-        $pageRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
+        $this->redirect('index');
+    }
+
+
+    /**
+     * Return the uid of the root page of the currently selected
+     * site, or null if no site's page is selected
+     *
+     * @return int | null
+     */
+    public function getCurrentRootPageUid() {
+        // Get the current page uid
         $pageId = (int) GeneralUtility::_GP('id');
-        $page = $pageRepository->getPage($pageId);
 
         // Get the root page of the site
-        $pageRepository = new OtPageRepository();
-        $rootPage = $pageRepository->getRootPageFor($pageId);
+        $otPageRepository = new OtPageRepository();
+        $rootPage = $otPageRepository->getRootPageFor($pageId);
 
-        // If the current page is not a root page or a subpage of one, abort
-        $pageSelected = ($rootPage['uid'] > 0);
-        $this->view->assign('pageSelected', (int)$pageSelected);
-        if (!$pageSelected) {
-            return;
+        if (!$rootPage['uid'] > 0) {
+            return null;
         }
 
-        $this->view->assign('rootPage', $rootPage);
-        $this->view->assign('themes', self::themes);
+        return (int)$rootPage['uid'];
+    }
+
+    /**
+     * Cleans the pages cache
+     */
+    public function cleanCache() {
+        $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
+        $dataHandler->start([], []);
+        $dataHandler->clear_cacheCmd('pages');
     }
 
     /**

+ 20 - 0
ot_templating/Classes/Utilities/OtPageRepository.php

@@ -67,5 +67,25 @@ class OtPageRepository extends PageRepository
         return $subpages;
     }
 
+    /**
+     * Returns the current site template's name
+     * @param $pageUid
+     * @return string
+     */
+    public function getCurrentTemplate($pageUid) {
+        $rootPageUid = $this->getRootPageFor($pageUid)['uid'];
+        if (!($rootPageUid >= 0)) {
+            return '';
+        }
+
+        $rootPage = $this->getPage($rootPageUid);
+        $templateName = $rootPage['tx_opentalent_template'];
+
+        if ($templateName==='') {
+            return 'Classic';
+        }
+        return $templateName;
+    }
+
 
 }

+ 48 - 0
ot_templating/Classes/ViewHelpers/CurrentTemplateViewHelper.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers;
+
+
+use Closure;
+use Opentalent\OtTemplating\Utilities\OtPageRepository;
+use Opentalent\OtTemplating\ViewHelpers\RootPage\GetIdViewHelper;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+
+/**
+ * Returns the name of the current template
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     {ot:currentTemplate()}
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class CurrentTemplateViewHelper extends AbstractViewHelper
+{
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @param array $arguments
+     * @param Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @return int|null
+     */
+    public static function renderStatic(
+        array $arguments,
+        Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        if (TYPO3_MODE == 'FE') {
+            $pageUid = (int) $GLOBALS['TSFE']->id;
+        } else {
+            $pageUid = (int) GeneralUtility::_GP('id');
+        }
+
+        $pageRepository = new OtPageRepository();
+        return $pageRepository->getCurrentTemplate($pageUid);
+    }
+
+}

+ 41 - 16
ot_templating/Resources/Private/Templates/OtCustomizer/Index.html

@@ -1,25 +1,48 @@
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
+
 <f:layout name="Backend/Default" />
 
 <f:section name="content">
+
+    <v:variable.set name="currentTemplate"
+                    value="{ot:currentTemplate()}"/>
+
     <div class="ot-customizer">
         <f:if condition="{pageSelected}">
             <f:then>
 
-                <div class="themes">
-                    <f:for each="{themes}" as="theme" key="theme_name">
+                <div class="templates">
+                    <f:for each="{templates}" as="template" key="template_key">
 
-                        <div class="theme-card">
-                            <div class="theme-title">
-                                {theme.name}
+                        <div class="template-card">
+                            <div class="template-title">
+                                {template.name}
                             </div>
-                            <div class="theme-poster">
-                                <f:image src="{theme.picture}" alt="poster" />
+                            <div class="template-poster">
+                                <f:image src="{template.picture}" alt="poster" />
                             </div>
-                            <div class="theme-description">
-                                {theme.description}
+                            <div class="template-description">
+                                {template.description}
                             </div>
-                            <div class="theme-controls">
-                                <button>Sélectionner</button>
+                            <div class="template-controls">
+
+                                <f:if condition="{template_key}=={currentTemplate}">
+                                    <f:then>
+                                        <div class="active">Thème actif</div>
+                                    </f:then>
+                                    <f:else>
+                                        <f:link.action
+                                                action="selectTemplate"
+                                                arguments="{template_key: template_key}"
+                                                title="select"
+                                                class="btn"
+                                        >
+                                            Utiliser ce thème
+                                        </f:link.action>
+                                    </f:else>
+                                </f:if>
+
                             </div>
                         </div>
                     </f:for>
@@ -43,18 +66,20 @@
                         </div>
 
                         <div class="form-group">
-                            <label>Afficher le caroussel</label>
+                            <label>Afficher le caroussel d'images</label>
                             <input type="checkbox"
                                    class="checkbox-input"
                                    value="1">
                         </div>
 
                         <div class="actions">
-                            <button class="btn btn-primary"
-                                    type="submit"
-                                    value="1">
+                            <f:link.action
+                                    action="selectTemplate"
+                                    arguments="{template_key: template_key}"
+                                    title="select"
+                                    class="btn">
                                 Appliquer
-                            </button>
+                            </f:link.action>
                         </div>
                     </form>
                 </div>

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/1Col.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout 1Col, defined in layouts/[templateName]/1Col.html --></f:comment>
-<f:layout name="{settings.template}/1Col" />
+<f:layout name="{ot:currentTemplate()}/1Col" />
 
 <f:section name='Configuration'>
     <flux:form id="1col" label="Gabarit simple" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/3Col.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout 3Col, defined in layouts/[templateName]/3Col.html --></f:comment>
-<f:layout name="{settings.template}/3Col" />
+<f:layout name="{ot:currentTemplate()}/3Col" />
 
 <f:section name='Configuration'>
     <flux:form id="3col" label="Gabarit 3 Colonnes" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/Contact.html

@@ -1,6 +1,7 @@
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Contact, defined in layouts/[templateName]/Contact.html --></f:comment>
-<f:layout name="{settings.template}/Contact" />
+<f:layout name="{ot:currentTemplate()}/Contact" />
 
 <f:section name='Configuration'>
     <flux:form id="contact" label="Gabarit Formulaire de contact" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/Events.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Events, defined in layouts/[templateName]/Events.html --></f:comment>
-<f:layout name="{settings.template}/Events" />
+<f:layout name="{ot:currentTemplate()}/Events" />
 
 <f:section name='Configuration'>
     <flux:form id="events" label="Gabarit Evènements" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/Home.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Home, defined in layouts/[templateName]/Home.html --></f:comment>
-<f:layout name="{settings.template}/Home" />
+<f:layout name="{ot:currentTemplate()}/Home" />
 
 <f:section name='Configuration'>
     <flux:form id="home" label="Gabarit Accueil" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/Members.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Members, defined in layouts/[templateName]/Members.html --></f:comment>
-<f:layout name="{settings.template}/Members" />
+<f:layout name="{ot:currentTemplate()}/Members" />
 
 <f:section name='Configuration'>
     <flux:form id="members" label="Gabarit Adherents" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/MembersCa.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Members, defined in layouts/[templateName]/Members.html --></f:comment>
-<f:layout name="{settings.template}/MembersCa" />
+<f:layout name="{ot:currentTemplate()}/MembersCa" />
 
 <f:section name='Configuration'>
     <flux:form id="members_ca" label="Gabarit Membres CA" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/Structures.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Members, defined in layouts/[templateName]/Structures.html --></f:comment>
-<f:layout name="{settings.template}/Structures" />
+<f:layout name="{ot:currentTemplate()}/Structures" />
 
 <f:section name='Configuration'>
     <flux:form id="structures" label="Gabarit Structures adhérentes" extensionName="Opentalent.OtTemplating">

+ 2 - 1
ot_templating/Resources/Private/Templates/Page/StructuresEvents.html

@@ -1,8 +1,9 @@
 {namespace flux=FluidTYPO3\Flux\ViewHelpers}
 {namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
 
 <f:comment><!-- uses the layout Events, defined in layouts/[templateName]/Events.html --></f:comment>
-<f:layout name="{settings.template}/StructuresEvents" />
+<f:layout name="{ot:currentTemplate()}/StructuresEvents" />
 
 <f:section name='Configuration'>
     <flux:form id="structuresEvents" label="Gabarit Evènements des structures" extensionName="Opentalent.OtTemplating">

+ 35 - 9
ot_templating/Resources/Public/assets/Backend/style/ot_customizer.css

@@ -4,7 +4,7 @@
     flex-direction: row;
 }
 
-.ot-customizer .themes {
+.ot-customizer .templates {
     display: flex;
     flex-direction: column;
     overflow-y: scroll;
@@ -12,7 +12,7 @@
     border-right: #cccccc solid 2px;
 }
 
-.ot-customizer .theme-card {
+.ot-customizer .template-card {
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -21,35 +21,61 @@
     margin: 12px 24px;
     padding: 12px;
 
-    border: solid 1px #8c8c8c;
-    background-color: #e6e6e6;
+    border: 1px solid #e6e6e6;
+    box-shadow: 2px 3px 3px #737373;
 }
 
-.ot-customizer .theme-card > div {
+.ot-customizer .template-card > div {
     margin: 12px;
 }
 
-.ot-customizer .theme-title {
+.ot-customizer .template-title {
     font-size: 16px;
     color: #2b2b2b;
     font-weight: 600;
 }
 
-.ot-customizer .theme-poster {
+.ot-customizer .template-poster {
     max-width: 80%;
 }
 
-.ot-customizer .theme-poster img {
+.ot-customizer .template-poster img {
     max-height: 300px;
     max-width: 100%;
     width: auto;
 }
 
-.ot-customizer .theme-description {
+.ot-customizer .template-description {
     color: #3F3F3F;
     font-style: italic;
 }
 
+.ot-customizer .active {
+    color: #00802b;
+    font-weight: 600;
+    border: solid 1px #00802b;
+    border-radius: 4px;
+    padding: 6px;
+}
+
+.ot-customizer a.btn {
+    padding: 6px;
+
+    border: solid 1px #bbb;
+    border-radius: 2px;
+    background-color: #eee;
+    font-weight: 600;
+}
+
+.ot-customizer a.btn:hover {
+    text-decoration: none;
+    cursor: pointer;
+
+    color: #333;
+    background-color: #d5d4d4;
+    border-color: #9c9c9c;
+}
+
 .ot-customizer .customizer {
     flex: 1;
 }

+ 1 - 1
ot_templating/ext_tables.php

@@ -24,7 +24,7 @@ call_user_func(
                 'ot_customizer', // Submodule key
                 'top', // Position
                 array(
-                    'OtCustomizer' => 'index',
+                    'OtCustomizer' => 'index,selectTemplate',
                 ),
                 array(
                     'access' => 'user,group',