Explorar el Código

Version 1.2.9: Some preparations

Sebastian hace 6 años
padre
commit
423e52271f

+ 1 - 1
cache/lastCache.txt

@@ -1 +1 @@
-1543940450
+1544113772

+ 0 - 0
content/01-Welcome/00-Setup.md → content/00-Welcome/00-Setup.md


+ 0 - 0
content/01-Welcome/01-Write-Content.md → content/00-Welcome/01-Write-Content.md


+ 0 - 0
content/01-Welcome/02-Get-Help.md → content/00-Welcome/02-Get-Help.md


+ 1 - 0
content/00-Welcome/03-test.txt

@@ -0,0 +1 @@
+["# Add Title","Add Content"]

+ 0 - 0
content/01-Welcome/index.md → content/00-Welcome/index.md


+ 16 - 0
content/01-stellenanzeigen/00-job-einstellen.md

@@ -0,0 +1,16 @@
+# Stellenangebot veröffentlichen
+
+CMSstash erreicht pro Monat mehrere tausend CMS-Experten in ganz Deutschland. Detaillierte Angaben finden sie in den [Mediadaten](/mediadaten). Unternehmen können diese Reichweite nutzen und ihre Stellenanzeigen mit CMS-Bezug auf CMSstash veröffentlichen. Wir bieten folgende Konditionen an:
+
+| Kondition | Anzeige Standard | Anzeige Pro |
+|-----------|-----------|----------|
+| Laufzeit | 8 Wochen | 8 Wochen |
+| Exklusiver Teaser auf allen Seiten | Nein | 4 Wochen |
+| Tweets | 1 Tweet | 3 Tweets |
+| __Preis__  | **59,- Euro** | **159,- Euro** |
+| _(keine Ausweisung der Mwst. nach § 19 UStG)_ |  |  |
+
+## Stellenanzeige aufgeben
+
+Bei Interesse schreiben Sie uns gerne über [jobs@cmsstash.de](mailto:jobs@cmsstash.de) an oder nutzen Sie das Kontaktformular. Aufgrund der inhaltlichen Ausrichtung können wir nur Stellenangebote mit einem klaren Bezug zum Thema Content Management Systeme veröffentlichen.
+

+ 4 - 0
content/01-stellenanzeigen/index.md

@@ -0,0 +1,4 @@
+# Add Title
+
+Add Content
+

+ 69 - 0
plugins/contactform/contactform.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace Plugins\contactform;
+
+use \Typemill\Plugin;
+
+class ContactForm extends Plugin
+{
+	protected $item;
+	protected $originalHtml;
+	protected $pluginSettings;
+	
+    public static function getSubscribedEvents()
+    {
+		return array(
+			'onSessionSegmentsLoaded' 	=> 'onSessionSegmentsLoaded',
+			'onOriginalLoaded' 			=> 'onOriginalLoaded',
+			'onHtmlLoaded' 				=> 'onHtmlLoaded',
+		);
+    }
+
+	public function onSessionSegmentsLoaded($segments)
+	{
+		$this->pluginSettings = $this->getPluginSettings('contactform');
+		
+		if($this->getPath() == $this->pluginSettings['page'])
+		{
+			$data = $segments->getData();
+			$data[] = $this->pluginSettings['page'];
+			$segments->setData($data);
+		}
+	}
+	
+	public function onOriginalLoaded($original)
+	{		
+		if(substr($this->getPath(), 0, strlen($this->pluginSettings['area'])) === $this->pluginSettings['area'])
+		{
+			# get original html without manipulations
+			$this->originalHtml = $original->getHTML();
+		}
+	}
+	
+	public function onHtmlLoaded($html)
+	{		
+		if(substr($this->getPath(), 0, strlen($this->pluginSettings['area'])) === $this->pluginSettings['area'])
+		{
+			$content = $this->originalHtml;
+			
+			if($this->getPath() == $this->pluginSettings['page'])
+			{
+				# add css 
+				# $this->addCSS('/textadds/css/textadds.css');
+
+				# get Twig Instance and add the cookieconsent template-folder to the path
+				$twig 	= $this->getTwig();
+				$loader = $twig->getLoader();
+				$loader->addPath(__DIR__ . '/templates');
+
+				# fetch the template and render it with twig
+				$contactform = $twig->fetch('/contactform.twig', $this->pluginSettings);
+				
+				$content = $this->originalHtml . $contactform;
+			}
+			
+			$html->setData($content);
+			$html->stopPropagation();			
+		}
+	}
+}

+ 96 - 0
plugins/contactform/contactform.yaml

@@ -0,0 +1,96 @@
+name: ContactForm
+version: 1.0.0
+description: Integrate a google like text-add into each content page (file).
+author: Sebastian Schürmanns
+homepage: https://typemill.net
+licence: MIT
+
+settings:
+  page: ''
+  name: 'Name: '
+  email: 'E-Mail: '
+  subject: 'Subject: '
+  message: 'Message: '
+  button: 'Send Message'
+
+forms:
+  fields:
+
+    page:
+      type: text
+      label: Path to the page where to show the form
+      placeholder: 'path/to/page'
+      required: true
+
+    area:
+      type: text
+      label: Path to the area with original content
+      placeholder: 'path/to/rootpage'
+      required: true
+
+    name:
+      type: text
+      label: Label for Name Input Field
+      placeholder: 'Name: '
+      required: true
+
+    email:
+      type: text
+      label: Label for E-Mail-Field
+      placeholder: 'E-Mail: '
+      required: true
+
+    subject:
+      type: text
+      label: Label for Subject-Field
+      placeholder: 'Subject: '
+      required: true
+
+    message:
+      type: text
+      label: Label for Message
+      placeholder: 'Message: '
+      required: true
+
+    button:
+      type: text
+      label: Label for Button
+      placeholder: 'Send Message'
+      required: true
+
+    hint:
+      type: textarea
+      label: Text below button (use markdown)
+      placeholder: 'Add your legal text or other hints here'
+
+frontend:
+  fields:
+
+    name:
+      type: text
+      label: Label for Name Input Field
+      placeholder: 'Name: '
+      required: true
+
+    email:
+      type: text
+      label: Label for E-Mail-Field
+      placeholder: 'E-Mail: '
+      required: true
+
+    subject:
+      type: text
+      label: Label for Subject-Field
+      placeholder: 'Subject: '
+      required: true
+
+    message:
+      type: text
+      label: Label for Message
+      placeholder: 'Message: '
+      required: true
+
+    hint:
+      type: textarea
+      label: Text below button (use markdown)
+      placeholder: 'Add your legal text or other hints here'

+ 26 - 0
plugins/contactform/css/textadds.css

@@ -0,0 +1,26 @@
+.contentadd{
+	display: block;
+	position: relative;
+	width: 100%;
+	border-top: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+}
+.contentadd span{
+	position: absolute;
+	right: 10px;
+	top: 20px;
+	text-transform: uppercase;
+	color: #ccc;
+	font-size: 0.6em;
+}
+.contentadd h3{
+	margin-top: 20px;
+	margin-bottom: 0px;
+}
+.contentadd small{
+	margin: 0px;
+}
+.contentadd p{
+	margin-top: 0px;
+	margin-bottom: 20px;
+}

+ 40 - 0
plugins/contactform/templates/contactform.twig

@@ -0,0 +1,40 @@
+<form method="POST" action="{{ path_for('settings.save') }}">
+
+	<fieldset>
+
+		<div class="medium{{ errors.contact.name ? ' error' : '' }}">
+			<label for="contact[name]">{{ name }} *</label>
+			<input type="text" name="contact[name]" id="name" pattern=".{2,20}" required title="Use 2 to 20 characters." value="{{ old.contact.title ? old.contact.name : contact.name }}" />
+			{% if errors.contact.title %}
+				<span class="error">{{ errors.contact.name | first }}</span>
+			{% endif %}
+		</div>
+		<div class="medium{{ errors.contact.email ? ' error' : '' }}">
+			<label for="contact[email]">{{ email }} *</label>
+			<input type="text" name="contact[email]" id="email" pattern=".{2,20}" required title="Use 2 to 20 characters." value="{{ old.contact.email ? old.contact.email : contact.email }}" />
+			{% if errors.contact.title %}
+				<span class="error">{{ errors.contact.email | first }}</span>
+			{% endif %}
+		</div>
+		<div class="medium{{ errors.contact.subject ? ' error' : '' }}">
+			<label for="contact[email]">{{ subject }} *</label>
+			<input type="text" name="contact[subject]" id="subject" pattern=".{2,20}" required title="Use 2 to 20 characters." value="{{ old.contact.subject ? old.contact.subject : contact.subject }}" />
+			{% if errors.contact.title %}
+				<span class="error">{{ errors.contact.email | first }}</span>
+			{% endif %}
+		</div>
+		<div class="medium{{ errors.contact.message ? ' error' : '' }}">
+			<label for="contact[email]">{{ message }} *</label>
+			<input type="textfield" name="contact[message]" id="message" pattern=".{2,20}" required title="Use 2 to 20 characters." value="{{ old.contact.message ? old.contact.message : contact.message }}" />
+			{% if errors.contact.title %}
+				<span class="error">{{ errors.contact.message | first }}</span>
+			{% endif %}
+		</div>
+		<small>{{ hint }}</small>
+		
+	</fieldset>
+	
+	<input type="submit" value="{{ button }}" />
+	{{ csrf_field() | raw }}	
+
+</form>

+ 6 - 2
system/Controllers/PageController.php

@@ -13,6 +13,7 @@ use Typemill\Models\Markdown;
 use Typemill\Events\OnPagetreeLoaded;
 use Typemill\Events\OnBreadcrumbLoaded;
 use Typemill\Events\OnItemLoaded;
+use Typemill\Events\OnOriginalLoaded;
 use Typemill\Events\OnMarkdownLoaded;
 use Typemill\Events\OnContentArrayLoaded;
 use Typemill\Events\OnHtmlLoaded;
@@ -118,6 +119,9 @@ class PageController extends Controller
 			$contentMD 		= isset($filePath) ? file_get_contents($filePath) : false;			
 		}
 		
+		# dispatch the original content without plugin-manipulations for case anyone wants to use it
+		$this->c->dispatcher->dispatch('onOriginalLoaded', new OnOriginalLoaded($contentMD));
+		
 		$contentMD = $this->c->dispatcher->dispatch('onMarkdownLoaded', new OnMarkdownLoaded($contentMD))->getData();
 		
 		/* initialize parsedown */
@@ -136,7 +140,7 @@ class PageController extends Controller
 		/* parse markdown-content-array to content-string */
 		$contentHTML	= $parsedown->markup($contentArray);
 		$contentHTML 	= $this->c->dispatcher->dispatch('onHtmlLoaded', new OnHtmlLoaded($contentHTML))->getData();
-
+		
 		/* extract the h1 headline*/
 		$contentParts	= explode("</h1>", $contentHTML);
 		$title			= isset($contentParts[0]) ? strip_tags($contentParts[0]) : $settings['title'];
@@ -155,7 +159,7 @@ class PageController extends Controller
 			$lastSpace 		= strrpos($description, ' ');
 			$description 	= substr($description, 0, $lastSpace);
 		}
-				
+
 		/* get url and alt-tag for first image, if exists */
 		if($firstImage)
 		{

+ 6 - 1
system/Controllers/SettingsController.php

@@ -49,9 +49,14 @@ class SettingsController extends Controller
 				);
 				
 				$copyright 					= $this->getCopyright();
-								
+
 				$validate->settings($newSettings, $copyright, 'settings');
 			}
+			else
+			{
+				$this->c->flash->addMessage('error', 'Wrong Input');
+				return $response->withRedirect($this->c->router->pathFor('settings.show'));				
+			}
 			
 			if(isset($_SESSION['errors']))
 			{

+ 35 - 0
system/Events/OnOriginalLoaded.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Typemill\Events;
+
+use Symfony\Component\EventDispatcher\Event;
+
+use Typemill\Extensions\ParsedownExtension;
+
+/**
+ * Event for html page.
+ */
+
+class OnOriginalLoaded extends Event
+{
+    protected $data;
+
+    public function __construct($data)
+    {
+        $this->data = $data;
+    }
+
+    public function getMarkdown()
+    {
+        return $this->data;
+    }
+	
+	public function getHTML()
+	{
+		$parsedown 		= new ParsedownExtension();
+		$contentArray 	= $parsedown->text($this->data);
+		$contentHTML 	= $parsedown->markup($contentArray);
+		
+		return $contentHTML;
+	}
+}

+ 14 - 0
system/Events/OnSessionSegmentsLoaded.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace Typemill\Events;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Event for breadcrumb.
+ */
+ 
+class OnSessionSegmentsLoaded extends BaseEvent
+{
+
+}

+ 1 - 1
system/Models/Validation.php

@@ -357,7 +357,7 @@ class Validation
 				break;
 			case "text":
 				$v->rule('lengthMax', $fieldName, 200);
-				$v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!]*$/u');
+				$v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!\/\:]*$/u');
 				break;
 			case "textarea":
 				$v->rule('lengthMax', $fieldName, 1000);

+ 11 - 1
system/Plugin.php

@@ -6,7 +6,7 @@ use \Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 abstract class Plugin implements EventSubscriberInterface
 {	
-	private $container;
+	protected $container;
 
     /**
      * Constructor
@@ -17,6 +17,16 @@ abstract class Plugin implements EventSubscriberInterface
     {
 		$this->container 	= $container;
     }
+	
+	protected function getSettings()
+	{
+		return $this->container->get('settings');
+	}
+	
+	protected function getPluginSettings($plugin)
+	{
+		return $this->container->get('settings')['plugins'][$plugin];
+	}
 
 	protected function getRoute()
 	{

+ 1 - 0
system/author/js/vue-blox.js

@@ -19,6 +19,7 @@ const contentComponent = Vue.component('content-block', {
 	methods: {
 		switchToEditMode: function()
 		{
+			if(this.edit){ return; }
 			eventBus.$emit('closeComponents');
 			self = this;
 			self.$root.$data.freeze = true; 						/* freeze the data */

+ 11 - 5
system/system.php

@@ -2,6 +2,7 @@
 
 use Typemill\Events\OnSettingsLoaded;
 use Typemill\Events\OnPluginsLoaded;
+use Typemill\Events\OnSessionSegmentsLoaded;
 
 /****************************
 * CREATE EVENT DISPATCHER	*
@@ -103,13 +104,18 @@ $container['assets'] = function($c)
 * 	DECIDE FOR SESSION	*
 ************************/
 
-$session_segments = array('setup', 'tm/', 'api/', '/setup', '/tm/', '/api/');
-$path = $container['request']->getUri()->getPath();
-$container['flash'] = false;
-$container['csrf'] = false;
+$session_segments 	= array('setup', 'tm/', 'api/', '/setup', '/tm/', '/api/');
+
+# let plugins add own segments for session, eg. to enable csrf for forms
+$client_segments 	= $dispatcher->dispatch('onSessionSegmentsLoaded', new OnSessionSegmentsLoaded([]))->getData();
+$session_segments	= array_merge($session_segments, $client_segments);
+
+$path 				= $container['request']->getUri()->getPath();
+$container['flash']	= false;
+$container['csrf'] 	= false;
 
 foreach($session_segments as $segment)
-{	
+{
 	if(substr( $path, 0, strlen($segment) ) === $segment)
 	{		
 		// configure session