Another Blog about the Wide Web World
Header image

Author Archives: SiteGefuehl

Ihr habt bereits Fancybox 3 (komplett responsive und touchfähig) im Einsatz und möchtet den Pin It Button einfügen? Solange ihr auf eurer Seite nur Thumbnails einbindet und die großen Bilder erst in der Lightbox geladen werden, sollten eure Nutzer die Möglichkeit in der Fancybox erhalten eure Bilder zu pinnen.

Und so geht’s:

Schritt 1:

Füge das JavaScript vor dem schließenden body Tag ein.

<script async defer src="//assets.pinterest.com/js/pinit.js"></script>

Schritt 2:

Danach fügt ihr Fancybox laut dieser Anleitung ein. 

Schritt 3:

Ich füge den Pin It Button in die Beschreibung des Bildes ein. Ist eine Beschreibung vorhanden, wird diese erweitert.

Dazu habe ich folgenden Code geschrieben:



$(".fancybox").fancybox({
		caption : function( instance, item ) {
			var caption, link;

			if ( item.type === 'image' ) {
				var caption = $(this).data('caption');
				
				if (caption) {
					//set description to current title
					//this will set what posts
					var description = $(this).data('caption');
					//add pinterest button for title
					pin = '<a data-pin-do="buttonPin" data-pin-tall="true" data-pin-save="false" href="https://pinterest.com/pin/create/button/?url=' +
					encodeURIComponent(document.location.href) +
					'&amp;amp;amp;media=' +
					//put the path to the image you want to share here
					encodeURIComponent(this.href) +
					'&amp;amp;amp;description=' + description + '"><img src="/fileadmin/templates/img/pinterest.png" /></a>'
					//add title information
					+ '&amp;amp;amp;nbsp;<span>' + $(this).data('caption') + '</span>';
					return pin;
				} else {
					//add pinterest button for title
					caption = '<a data-pin-do="buttonPin" data-pin-tall="true" data-pin-save="false" href="https://pinterest.com/pin/create/button/?url=' + 
					encodeURIComponent(document.location.href) +
					'&amp;amp;amp;media=' +
					encodeURIComponent(this.href) +
					'&amp;amp;amp;description=Pin%20von%20finca-ferienhaus.de%20Ferienh%C3%A4user%20und%20Fincas%20auf%20Mallorca"><img src="/fileadmin/templates/img/pinterest.png" /></a>';
					return caption;
				}

				
			}
		}
		
	});


Dieser muss natürlich in euren document ready Aufruf.

$(document).ready(function () { hier den oben gennanten Code einfügen });

Die Standard Beschreibung des Pins müsst ihr natürlich gegen die Beschreibung eurer Website austauschen. Außerdem habe ich mir einen eigenen Button erstellt.

Und so sieht es dann aus:

Fancybox 3 mit einem Pinterest Button

Mein Ziel war es von Fluid heraus die uid einer Seite an TypoScript zu übergeben



<f:cObject typoscriptObjectPath="lib.caseStudyImage" data="{casestudy}" />


Jedes Object casestudy hatte eine UID, die die uid einer Seite war. Es wurden über eine foreach Schleife mehrere Case Studys ausgegeben. Bei der Ausgabe dieser Case Studys sollte dann aus dem Inhalt der jeweiligen Seite das erste Bild ausgegeben werden.

Leider hat kein einziger Code, den ich im Netz gefunden habe korrekt mit FAL funktioniert. Daher hier meine Lösung


lib.caseStudyImage = CONTENT
lib.caseStudyImage {
	table = tt_content
	select {
		languageField = sys_language_uid
		orderBy = sorting
		max = 1
		where = (CType = "image" OR CType = "textpic") AND colPos = 0 
		pidInList.field = uid
	}
	renderObj = FILES
	renderObj {
		begin = 0
		maxItems = 1
		references {
			table = tt_content
			uid.data = uid
			fieldName = image
		}
		renderObj = IMAGE
		renderObj {
			file.import.data = file:current:uid
			file.treatIdAsReference = 1
			file.width = 335c
			file.height = 220c
			altText.data = file:current:title
		}
	}
}

et voila


temp.categorymenu = COA
temp.categorymenu.20 = CONTENT	
temp.categorymenu.20 {
	table = tx_news_domain_model_category
	select {
		selectFields = tx_news_domain_model_category.title, tx_news_domain_model_category.description
		pidInList = {$storage}
		join = tx_news_domain_model_news_category_mm ON (tx_news_domain_model_category.uid = tx_news_domain_model_news_category_mm.uid_foreign) INNER JOIN tx_news_domain_model_news ON (tx_news_domain_model_news.uid = tx_news_domain_model_news_category_mm.uid_local)
		andWhere = tx_news_domain_model_news.uid = {GP:tx_news_pi1|news}
		andWhere.insertData = 1
		max = 1
	}
	renderObj = COA
	renderObj {
		10 = TEXT
		10 {
			field= title
			wrap = <h2>|</h2>
			htmlSpecialChars = 1
		}
		20 = TEXT
		20 {
			field= description
			wrap = <p>|</p>
			htmlSpecialChars = 1
		}
	}
}

TYPO3 Swift_RfcComplianceException

geschrieben von SiteGefuehl in TYPO3 - (0 Kommentare)

Wenn es mal wieder heißt

Address in mailbox given [@localhost] does not comply with RFC 2822, 3.6.2.
Swift_RfcComplianceException thrown in file [..]/MailboxHeader.php in line 309.

.. dann wird vermutlich in einer alten Extension noch die alte Mail API von TYPO3 genutzt.
Ich glaube sogar direct_mail hatte bei mir auch irgendwann den Fehler verursacht.
Da reichte es, wenn man im Install Tool folgende Einstellung aktivierte (substituteOldMailAPI).

Oder vielleicht liegt der Wurm auch im falschen Headers Bereich, der Mail. Siehe Bug 25295 im Forge.

Bei mir lies sich das Problem folgendermaßen lösen:
Schauen, welcher Code ausgeführt wird, wenn der Fehler auftritt. Es wird vermutlich ein Absenden eines Formulars sein, oder Ähnliches. Ich musste im Code der Extension dann nur noch nach den Stellen suchen, wo eine Email versendet wird.

Bei mir sah die Funktion folgendermaßen aus:
t3lib_div :: plainMailEncoded('', $subject, $message, $headers);

Die habe ich dann ersetzt durch die neue Mail API:

$mail = t3lib_div::makeInstance('t3lib_mail_message');
$mail->setFrom(array($email => $name));
$mail->setTo(array($email => $name));
$mail->setSubject($subject);
$mail->setBody($body);
$mail->send();

Mehr Infos zum SwiftMailer findet ihr auf Forge.

Tatsächlich ist bisher der Fehler nie aufgefallen. Erst jetzt! Da ich recht lange recherchieren musste, um eine Lösung zu finden, nehme ich das mal als Grund über das Problem in meinem Blog zu schreiben.

Ich hatte folgende Konstellation: Eine WordPress Instanz sollte über mehrere Domains erreichbar sein. In diesem Fall war es einmal die Hauptdomain www.xyz.de und die Subdomains namens stadt1.xyz.de + stadt2.xyz.de + stadt3.xyz.de + stadt4.xyz.de

Je nach Domain wurde ein anderer Inhalt ausgegeben. Dies habe ich mit einer kleinen HTTP Host Abfrage in WordPress gelöst.

Nun sollten auch Webfonts über font-face und auch die komplette Website über https laufen. Ich habe hier ein nettes, schlankes Plugin gefunden, welche alle Links (auch in der CSS Datei) zum Protokoll https zwingt (WordPress HTTPS war mir zu viel des Guten). So wird schonmal keine Info über unsichere Inhalte ausgegeben. Das Plugin nimmt einem die Arbeit ab, alle Inhalte und Plugins nach http Verbindungen abzusuchen.

Folgender Fehler trat nun auf: Besuchte man eine der Subdomains über den Firefox (bei mir war’s noch die Version 15) und dem IE9, so wurden die Webfonts nicht geladen. Ich probierte absolute Pfad, z.B. https://www.xyz.de/font.eot oder //font.eot oder /font.eot aus. Relative Pfade brachten leider auch nicht das gewünschte Ergebnis. Lustigerweise sah im Chrome auf den Subdomains alles super aus. Die Hauptdomain war auch in allen Browsern ok.

Nach einiger Zeit Recherche und nachdem ich die Web-Konsole über den Firefox öffnete, sah ich den Fehler:

Firefox meckerte aufgrund eines Cross-Domain Problems. Er versuchte nämlich weiterhin über die Hauptdomain die Fonts aufzurufen. Da man sich jedoch auf der Subdomain befand, wurden diese nicht aufgerufen.

Ich habe nun folgende Einstellungen in die .htaccess eingefügt:


AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType font/woff .woff

<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>

Die AddType Zeilen fügen die MIME types zur HTTP response hinzu. Danach prüfen wir, ob eine der Dateiendungen abgerufen wird und ob mod_headers vorhanden ist und erlauben den Zugriff über andere Domains.

Das Ganze kann man auch die Apache Config (z.B. hier zu finden /etc/apache2/apache2.conf ) schreiben.

Folgendermaßen sieht nun meine font-face CSS Bereich aus:


@font-face {
    font-family: "Font XY";
	src: url('https://www.xyz.de/wp-content/themes/xyz/fonts/Font-XY.eot'); 
	src: url('/wp-content/themes/xyz/fonts/Font-XY.woff') format('woff');
	font-weight: normal;
	font-style:normal;
}

Endergebnis: Anzahl Kommentare in der SINGLE Ansicht

Ihr benutzt tt_news und die comments Extensions? Komischerweise ist die Ausgabe der Anzahl der Kommentare nur in der LIST, LATEST und SEARCH Ansicht möglich. Was müsst ihr machen, um die Anzahl der Kommentare auch in der SINGLE Ansicht anzeigen zu lassen? Leider in die Extension eingreifen!

Dort wird die Art des tt_news Views über Strings abgefragt. In der Funktion extraItemMarkerProcessor (ca ab Zeile 64) in der Datei class.tx_comments_ttnews.php unter typo3conf/ext/comments/.

In dieser Funktion werden die Marker mit Inhalt befüllt.
Vorher wird über Switch abgefragt in welchem tt_news View ihr euch befindet.

Hier muss SINGLE hinzugefügt werden. Also muss euer Code so aussehen:


	function extraItemMarkerProcessor($markerArray, $row, $lConf, &amp;amp;amp;$pObj) {
		/* @var $pObj tx_ttnews */
		switch ($pObj->theCode) {
			case 'LATEST':
			case 'LIST':
			case 'SEARCH':
			case 'SINGLE':
				// Add marker for number of comments
				$commentCount = $this->getNumberOfComments($row['uid'], $pObj);
				$templateName = $commentCount ? '###TTNEWS_COMMENT_COUNT_SUB###' : '###TTNEWS_COMMENT_NONE_SUB###';
				if (($template = $this->getTemplate($templateName, $lConf, $pObj))) {
					$lang = t3lib_div::makeInstance('language');
					/* @var $lang language */
					$lang->init($GLOBALS['TSFE']->lang);
					$markerArray['###TX_COMMENTS_COUNT###'] = $pObj->cObj->substituteMarkerArray(
						$template, array(
							'###COMMENTS_COUNT_NUMBER###' => $commentCount,
							'###COMMENTS_COUNT###' => sprintf($lang->sL('LLL:EXT:comments/locallang_hooks.xml:comments_number'), $commentCount),
							'###COMMENTS_COUNT_NONE###' => $lang->sL('LLL:EXT:comments/locallang_hooks.xml:comments_number_none'),
							'###UID###' => $row['uid'],
							'###COMMENTS_LINK###' => $this->getItemLink($markerArray['###LINK_ITEM###'], $row['uid'], $pObj),
						)
					);
					unset($lang);	// Free memory explicitely!
				}
				break;
		}
		return $markerArray;
	}

Natürlich muss auch der Marker ###TX_COMMENTS_COUNT### in euer tt_news SINGLE Template eingefügt werden.

Tjaa… Da habe ich mal wieder etwas umgestellt, hab es dann vergessen und irgendwann während ich wieder mit TextMate gearbeitet habe, fiel die Änderung auf. Egal wo man in der Datei hingeklickt hat, der Cursor blieb dort stehen, auch wenn es mitten in einer leeren Zeile war.
Ich hätte gerne gewollt, dass er an das Ende der jeweiligen Zeile geht. Die Tab-Abstände (Tabs) haben auch nicht mehr so richtig das gemacht, was ich wollte.
Um einigen vielleicht etwas Arbeit zu ersparen, hier nun die Lösung des Problems. Geht man auf Mode > Freehanded Editing und deaktiviert den zuvor eingestellte Modus, dann landet man bei Klick auf eine Zeile auch wieder am Ende einer Zeile. Wie zuvor von mir vermutet, hat das alles leider nichts mit den “Line Endings” unter Preferences zu tun.

mm_forum ist sehr mächtig und somit kann eine kleine Änderung schonmal ganz anstrengend werden.. Leider habe ich bisher keine bessere Methode gefunden,  um den Antworten Button von unter den Posts nach oben zu verschieben. Im Template “list_post.html” ist der Reply Button im Marker ###POSTBOTTOM### versteckt. Der Marker wird aber nur befüllt, wenn er sich auch zwischen dem subpart <!-- ###LIST_POSTS_END### begin --> und <!-- ###LIST_POSTS_END### end --> befindet. Würde man ###POSTBOTTOM###  nun zwischen <!-- ###LIST_POSTS_BEGIN### begin --> und <!-- ###LIST_POSTS_BEGIN### end --> einfügen, würde der Marker nicht ersetzt werden. Lösung hierfür:

In der Datei class.tx_mmforum_postfunctions.php unter ext/mm_forum/pi1 sollte man (je nach Version) ab ca. Zeile 222, also nach // Output topic name den Code für die $this->createButton('reply', $linkParams) Funktion einfügen. Der sieht folgendermaßen aus:


if ((!$topicData['read_flag'] && !$topicData['closed_flag']) || $this->getIsMod($topicData['forum_id']) || $this->getIsAdmin()) {
			if ($this->getMayWrite_topic($topicId)) {
				$linkParams[$this->prefixId] = array(
					'action' => 'new_post',
					'tid'    => $topicId
				);
				if ($this->useRealUrl()) {
					$linkParams[$this->prefixId]['fid'] = $topicData['forum_id'];
				}
				$marker['###POSTBOTTOM###'] = $this->createButton('reply', $linkParams);
			} else {
				$marker['###POSTBOTTOM###'] = '';
			}
		} else {
			$marker['###POSTBOTTOM###'] = $this->pi_getLL('topic.adminsOnly');
		}

Ich musste viel probieren, bis ich zu einer geeigneten Lösung kam. Mein IST Zustand: Ich habe über einen Link eine Slideshow mit der Fancybox geöffnet. In dem iframe befand sich eine “ganz normale” Seite (eigenes Template in TYPO3). Nun wollte, dass sich die Fancybox auch schließt, wenn ich auf einen bestimmten Link klicke.

Etliche Aufrufe über eine Funktion haben nicht geklappt. Erfolg brachte onclick:

onclick="window.top.$.fancybox.close();"

Danke an Bastian Bringenberg.

Ich konnte es kaum glauben, dass ich so lange an der Lösung eines manuellen (ohne Extension, sondern nur mit TypoScript) printlinks saß. Teilweise waren die Lösungen veraltet (z.B. GPvar anstatt GP) oder nahmen keine Rücksicht auf die Get Variablen von tt_news. Außerdem war es mir wichtig, dass ich nicht direkt über JavaScript ein window.print aufrufe und dann “nur” noch die print.css genommen wird. Ich wollte ein komplett neues Template, somit eine Druck-Vorschaufunktion für den User und erst dann das automatische OS Druck-Fenster. Das TypoScript kann natürlich nach belieben angepasst werden.

Hiermit erstelle ich den Printlink und später kopiere ich ihn einen Marker.


temp.print-link = COA
temp.print-link {
	10 = TEXT
	10.value = Seite drucken
	stdWrap.wrap = |
	stdWrap.typolinkno_cache = 1
	stdWrap.typolink.target = print
	stdWrap.typolink.ATagParams = target = _top
	stdWrap.typolink.parameter.cObject = COA
	stdWrap.typolink.parameter.cObject {
 
        5 = TEXT
        5.data = page:uid
        5.wrap = index.php?id=|
        5.required = 1
 
        10 = TEXT
        10.value = &amp;amp;amp;no_cache=1
 
        20 = TEXT
        20.data = GP:L
        20.wrap = &amp;amp;amp;L=|
        20.required = 1
 
        30 = TEXT
        30.data = GP:tx_ttnews | backPid
        30.wrap = &amp;amp;amp;tx_ttnews[backPid]=|
        30.required = 1
 
        40 = TEXT
        40.data = GP:tx_ttnews | tt_news
        40.wrap = &amp;amp;amp;tx_ttnews[tt_news]=|
        40.required = 1
 
        50 = TEXT
        50.data = GP:cHash
        50.wrap = &amp;amp;amp;cHash=|
        50.required = 1
 
        60 = TEXT
        60.value = &amp;amp;amp;type=98
    }
}

Und hiermit definiere ich das Drucktemplate


print = PAGE
print {
  typeNum = 98
  bodyTag = <body onload="javascript:window.print()">   
  ##disable typo3 index
  config.index_enable = 0
 
  ##disable google index
  headerData.123 = TEXT
  headerData.123.value = <meta name="robots" content="noindex, nofollow" />
 
  includeCSS.fileDefault = fileadmin/templates/css/print.css
  10 = TEMPLATE
  10 {
      template = FILE
      template.file = fileadmin/templates/print.tmpl
      workOnSubpart = DOCUMENT_BODY
 
      marks { 
        CONTENT < styles.content.get
      }      
   }
}