Google loves TYPO3 extensions

Erstellt: Donnerstag, 24. November 2016

After googling for a TYPO3 extension, I became aware that the search result looked different:

Search result for "typo3 cewrap"

Search result for „typo3 cewrap“

There are informations about how often this extension was downloaded, which category it belongs to, the last update of the extension and a link to the manual. For other extensions, there is also a link to the external repository, e.g. git.typo3.org, an information about the current version and more, it differs from extension to extension.

These informations are taken from the right side of the entry page of this extension in the TER (the TYPO3 Extension Repository):

Right side of EXT:cewrap in TER

Right side of EXT:cewrap in TER

The contents on the right side are not marked somehow as rich snippet / structured data, so it seems, Google (perhaps some kind of A.I. bot / machine learning crawler) recognized the TER and extracts these informations of their own accord.

Nice :)

Thema: Sonstiges, TYPO3 | Keine Kommentare

Meine Erfahrungen mit der Trading-App BUX

Geändert: Freitag, 10. Juni 2016 | Erstellt: Mittwoch, 8. Juni 2016

Durch einen Bericht auf ard.de bin ich auf die Trading App BUX aufmerksam geworden. Die App ist mittlerweile sehr beliebt, hat schon 400000 Benutzer und wird auch in Deutschland immer beliebter. In diesem Artikel möchte ich, als Trading Anfänger, meine Erfahrungen und Probleme mit BUX beschreiben.

Vergleich mit eToro

Ein direkter Vergleich mit eToro ist schwierig, eToro ist auf Social Trading spezialisiert, BUX ist lediglich eine App zum möglichst unkomplizierten Trading. Aber auch eToro hat eine App für das Trading und man kann in die gleichen Finanzmittel investieren, mit geringem Einsatz und ebenfalls gehebelt.

eToro sagt man nach, dass es recht hohe Gebühren verlangt, daher bin ich davon ausgegangen, dass ich mit BUX weniger Gebühren zahle und habe das anhand ein paar Trades geprüft (Achtung: Die Werte sind alle Näherungswerte und sollen nur einen groben Vergleich ermöglichen):

Anbieter Gebühr
1 Tag
Gebühr
14 Tage
Gebühr
28 Tage
Gebühr
1 Jahr
Eröffnungsgebühr / Spread Finanzierungsgebühr / Rollover*1 Abschlussgebühr
BUY GER30 (DAX) 50€, x10*2 eToro 0,33 € 0,61 € 1,17 € 14,70 € 0,05 $ bzw. 0,044 €*3 0,045 $ bzw. 0,04 €*3
0,1375 $ bzw. 0,1219 € Wochenende*3
0 €
BUX 0,63 € 1,02 € 1,44 € 11,52 € 0,3 € 0,03 €
0,09 € Wochenende
0,3 €
BUY GER30 (DAX) 500€, x1*2 eToro 0,35 € 0,65 € 1,25 € 15,65 € 0,05 $ bzw. 0,044 €*3 0,05 $ bzw. 0,044 €*3
0,14 $ bzw. 0,124 € Wochenende*3
0 €
BUX 0,60 € 0,60 € 0,60 € 0,60 € 0,3 € 0 € 0,3 €
SELL GER30 (DAX) 50€, x10*2 eToro 0,044 € 0,044 € 0,044 € 0,05 $ bzw. 0,044 €*3 0 € 0 €
BUX TBD*4
BUY/SELL OIL 30€, x10*2 eToro 0,31 € 0,31 € 0,31 € 0,31 € 0,31 €*3 0 € 0 €
BUX 0,60 € 0,60 € 0,60 € 0,60 € 0,3 € 0 € 0,3 €
BUY EUR/USD TBD*4
BUY USD/JPY TBD*4


*1
Gebühr pro Tag, über das Wochenende sind die Gebühren in der Regel höher (die dreifache Gebühr).
*2 Hebel / Multiplikator
*3 Bei eToro wird in USD gehandelt, Umrechnung in EUR: 1€ = 1,13$
*4 Diese Werte ergänze ich, sobald ich die Trades durchgeführt habe

Man sieht also, dass die Gebühren bei BUX meist deutlich höher sind. Nur bei längerer Haltedauer oder bei ungehebelten Trades gibt es bei BUX Vorteile.

Vorteile BUX

  1. Einfacher Einstieg in Börsenhandel.
  2. Keine Finanzierungsgebühren (Rollover) bei ungehebelten Trades.
  3. Geringe Gebühren bei Trades mit hohen Geldeinsatz und langer Haltedauer (> 14 Tage, je nach Finanzinstrument).

Nachteile BUX

  1. Hohe Gebühren im Vergleich mit anderen Anbietern.
  2. Sehr hohe Mindestgebühr: Erst bei Trades mit einer Gesamthöhe von 250 bis 400 € (je nach Handelsinstrument) übersteigt die für das Öffnen und Schließen von Trades anfallende Gebühr die Mindestgebühr in Höhe von 0,50 €. D.h. bei Trades mit geringer Gesamthöhe sind die Gebühren anteilig sehr hoch, z.B. bei einem Trade in Höhe von 10 € beträgt die Mindestgebühr 5%, bei einem Trade in Höhe von 500 € nur ca. 0,2% (abhängig vom Handelsinstrument).
  3. Sehr intransparente Gebühren: Bei der Eröffnung eines Trades wird nicht angezeigt, wie hoch die Finanzierungsgebühren (Rollover) sein werden.
  4. Einschränkungen beim Trading
    1. Es können keine Limit-Aufträge (z.B. kaufe Öl zum Kurs von 50$ und verkaufe zum Kurs von 40$) erteilt werden.
    2. Stop Loss und Take Profit können nur als prozentualer Anteil zum eingesetzten Kapital angegeben werden, nicht aber in absoluten Zahlen. Das ist z.B. wichtig, wenn man beim Trading psychologische Marken in Betracht ziehen möchte, wie z.B. 10000 Punkte beim DAX oder zuletzt 40$ bei Öl.
  5. Nach der Umstellung auf Echtgeld entfällt die Möglichkeit, mit Spielgeld zu trainieren. Da man bei der Umstellung auf Echtgeld ein Bonus von 5 € erhält, aber nur in einem zeitlich begrenzten Rahmen, werden viele Benutzer vermutlich verfrüht auf Echtgeld umstellen. Eine jederzeit mögliche Umschaltung zwischen Echt- und Spielgeld wäre besser gewesen.
  6. Bonusse werden nur indirekt ausgezahlt: Die Bonusse (z.B. für Umstellung auf Echtgeld oder für das Werben von Freunden) werden nicht direkt gutgeschrieben, sondern mit den Gebühren verrechnet. Erst wenn so viele Gebühren angefallen sind, dass diese die Höhe eines Bonusses betragen, kann der Bonus eingelöst werden.
  7. Bonusse verfallen: Die Bonusse haben nur eine sehr kurze Gültigkeit (ca. 4 Wochen) und verfallen dann. Es erfolgt auch keine anteilige Gutschrift (z.B. wenn man durch angefallene Gebühren bereits 90% seines 5€-Bonusses erreicht hat).
  8. Battles für Anfänger ungeeignet: Man wird durch die Battles mit anderen Tradern zum unüberlegten Trading verführt: Um besser als die Mitspieler zu sein und einen Battle zu gewinnen, tätigt man riskante Trades.

Fazit

Bux Profil

Mein BUX Profil. 36 Trades bedeutet 18 geöffnet, 18 geschlossen

Trotz der positiven Entwicklung meines Investments (mit 100€ begonnen, nun 190€, alle 18 Trades ohne Verlust) werde ich BUX wohl nicht weiter nutzen und wenn, dann nur für ungehebelte Trades. Der Hauptgrund sind die hohen Gebühren, bei dem Gewinn von 90 € mit den 18 Trades (die ich immer nur wenige Stunden, manchmal Tage, offen hatte) betrugen die Gebühren ca. 10 € (ca. 11% der erwirtschafteten Gewinne!). Nach dem Abführen der Kapitalertragssteuer von 25% gehen von meinem Gewinn also insgesamt 36% ab.
Daneben störe ich mich vor allem noch an den intransparenten Rollover-Gebühren und den wenigen Trading-Optionen (keine Aufträge erteilbar, kein SL/TP zu festen Werten).

 

Diese Einschätzung wurde im Juni 2016 erstellt, beachte bitte, dass es in der Zwischenzeit Änderungen an der App oder den Gebühren gegeben haben könnte. Ich werde den Artikel aktuell halten, es lohnt sich also, zu einem späteren Zeitpunkt nochmals vorbei zu kommen.

Thema: Anlagestrategie | Keine Kommentare

TYPO3 Hosting – Eigenheiten der ISPs

Geändert: Donnerstag, 29. September 2016 | Erstellt: Dienstag, 24. März 2015

Für verschiedene Kunden – und auch für mich selbst – verwalte ich bei diversen Hostern Webhosting Pakete und auch Managed Server. Dabei kommt es, in Verbindung mit TYPO3, immer wieder zu Schwierigkeiten, auf die ich in diesem Artikel näher eingehen möchte.

Gab es früher häufig Probleme mit ImageMagick bzw. GraphicsMagick, so bietet mittlerweile jeder Hoster diese Software an. Probleme gibt es nun häufig bei Cronjobs oder in Verbindung mit htaccess. Außerdem sind aus Sicherheitsaspekten oft bestimmte PHP Funktionen deaktiviert, wie zum Beispiel Funktion „exec„, die TYPO3 an bestimmten Stellen einsetzt.

Domainfactory: Einbindung der TYPO3 Sourcen mit Symlinks

Idealerweise legt man die TYPO3 Sourcen außerhalb des Web-Verzeichnisses ab und verweist darauf per Symlink. Bei der aktuellen TYPO3 Version wären das zwei Symlinks, einer auf das Verzeichnis „typo3„, einer auf die Datei „index.php„. Bei Domainfactory ist ein Symlink auf „index.php“ nicht möglich.

Begründung:

Symlinks sind bei uns aus Sicherheitsgründen nur auf nicht ausführbare Ziele wie z.B. Ordner oder Bilder möglich.

und

Symlinks auf ausführbare Dateien sind bei uns verboten, da dies bei bestimmten Konstellationen andere Sicherheitsmerkmale wie z.B. Quotas umgehen könnte.

Resultierende Probleme:

  1. Keine vollständige Einbindung der Sourcen möglich, die Datei „index.php“ muss in das Web-Verzeichnis kopiert werden.
  2. Warnungen im Install-Tool: „Path /index.php is not a link
  3. TYPO3 „Core Update“ aus dem Install-Tool heraus nicht möglich: TYPO3 verweigert das Update wegen den Warnungen (siehe 2.)

Domainfactory: Setzen des Application Contextes

In TYPO3 kann man verschiedene Kontexte definieren, z.B. „Development“ oder „Production„. Standardmäßig wird dieser Kontext über die htaccess Datei gesetzt:

RewriteCond %{HTTP_HOST} ^dev\.example\.com$
RewriteRule .? - [E=TYPO3_CONTEXT:Development]

Bei Domainfactory führt diese Anweisung aber nicht zu dem gewünschten Ergebnis, in PHP ist die Kontext-Variable leer.

Begründung:

PHP wird bei uns unter CGI ausgeführt und nicht als Modul des Webservers weshalb Umgebungsvariablen des Webservers nicht an PHP übergeben werden.

Domainfactory: Cronjobs

Einen Cronjob auf den „TYPO3 Scheduler“ funktioniert nicht wie von TYPO3 vorgesehen, mit der Anweisung „/typo3/cli_dispatch.phpsh scheduler„, sondern man muss den Umweg über eine .sh-Datei mit folgenden Inhalt gehen:

#!/bin/bash
env -i /usr/local/bin/php -f /kunden/kunden-id/pfad/zu/typo3/cli_dispatch.phpsh scheduler

Aktuell läuft bei Domainfactory noch PHP 4. Wenn man eine neuere PHP-Version einsetzen möchte oder ein höheres Memory-Limit benötigt, muss man dies beim Aufruf angeben:

#!/bin/bash
env -i /usr/local/bin/php5-55STABLE-CLI -d memory_limit=512M -f /kunden/kunden-id/pfad/zu/typo3/cli_dispatch.phpsh scheduler

DomainFactory: Langsame Datenbank

DomainFactory setzt eine Konsistenzprüfung ein, die jeden Schreibvorgang in die Datenbank loggt.

Begründung:

Wir setzen auf unseren neuesten Server-Generationen das Dateisystem ext4 ein. Bei diesem Dateisystem ist eine Konsistenz-Prüfung (sogenannte „barriers“) aktiv, die jeden Schreibvorgang validiert. Dies erhöht die Datenintegrität und Datensicherheit, hat jedoch auf Auswirkungen auf die Schreib-Performance, die sich jedoch im normalen Betrieb kaum bemerkbar machen.
In Verbindung mit der MySQL-Tabellen-Engine InnoDB kommt es hierbei jedoch zu einer Verlangsamung der InnoDB-Schreibaktionen. In den Standard-Einstellungen, die von den Entwicklern empfohlen werden, wird jede InnoDB-Schreibaktion (UPDATE, INSERT) direkt auf das Log auf der Festplatte synchronisiert. Wenn hier nun viele solcher Aktionen durchgeführt werden, wie dies z.B. beim Import eines Dumps oder Änderungen im Backend eines CMS-Systems wie Typo3 der Fall ist, dann verlangsamt sich hier der gesamte Vorgang, da jeder einzelne Schreibzugriff eine geringe Verzögerung aufweist.

Diese „geringe Verzögerung“ betrugt bei mir, bei einfachsten UPDATE und INSERT Queries, laut Slow Queries Log bis zu 4 Sekunden.

Lösung:

DomainFactory hat folgendes vorgeschlagen:

Es gibt hier nun jedoch die Möglichkeit die Einstellungen des MySQL-Servers so anzupassen, dass nicht jede InnoDB-Aktion direkt einen Schreibvorgang auf der Festplatte auslöst. Im Detail handelt es sich um eine Anpassungen der Option „innodb_flush_log_at_trx_commit“. Der MySQL-Dienst kann durch Veränderung dieser Option auch automatisch alle 1-3 Sekunden im Hintergrund eine Synchronisation ausführen. Hierdurch wird die Verlangsamung der InnoDB-Aktionen dann stark geschwächt. Da es hierbei aber mit einer sehr geringen Wahrscheinlichkeit zu einem Datenverlust von wenigen Sekunden kommen kann, ändern wir die Einstellung des Dienstes hier nur mit der expliziten Zustimmung unseres Kunden.

Ob diese Einstellung Erfolg hat, muss ich noch prüfen.

Alfahosting: Cronjobs

Mit Cronjobs gibt es bei Alfahosting öfters Probleme. Teilweise findet der Support diesen Fehler schnell…

[…]der Cronjob ist aus leider unbekannten Grund „hängen geblieben“ und läuft ab sofort wieder.

…aber es kam auch schon vor, dass erst nach 14 Nachrichten im Ticket erkannt wird:

[…]nach nochmaliger Prüfung, stellte sich nun heraus, dass der Fehler beim Cron selbst lag, nicht am Script. Wir mussten als Workaround die Shebang komplett entfernen und den Interpreter auf PHP 5.4 stellen.

Man muss auch wissen, dass ein Cronjob bei Alfahosting deaktiviert wird, sobald er 10 Mal mit einem Fehlerstatus endet. Wenn man ihn im Konfigurationsmenü erneut abspeichert, ist er wieder aktiv.

Nicht verständlich ist mir, wieso bei Alfahosting Cronjobs (ebenso wie bei Domainfatory) standardmäßig mit PHP Version 4 ausgeführt werden. Man kann zwar in den Server-Einstellungen des Kundenaccounts eine andere PHP Version einstellen, das hat aber keine Auswirkung auf die PHP Version, die in der Kommandozeile genutzt wird.

[…]mit /usr/bin/php sprechen Sie nur PHP 4 an. Das ist nun einmal der Pfad auf dem Server.

Lösung: Shebang in Datei cli_dispatch.phpsh ändern auf

#! /usr/bin/php5.4 -q

Resultierende Probleme: Bei einem TYPO3 Update werden diese Änderungen überschrieben und der Cronjob wird wieder nicht funktionieren. Dazu schreibt Alfahosting:

Wenn Typo3 das Shebang beim Update überschreibt und dies ist kein gewünschter Vorgang, kann nur Typo3 das Problem lösen. Wir empfehlen, dazu einmal den Support von Typ3 zu kontaktieren. Eventuell gibt dort schon einen Workaraound zu dieser Problematik.

Mittwald: TYPO3 Caching

Auf einem Mittwald Server hatte ich bei einem großen TYPO3 Portal schon das Phänomen, dass bestimmte Seiten von TYPO3 partout nicht gecached wurden, nach dem Leeren des Caches hat es für bestimmte Seiten funktioniert (für die es zuvor nicht funktioniert hat), allerdings nur bis zum nächsten Cache-Leeren. Für dieses Problem habe ich keine Lösung gefunden. Nach einem Umzug zu Domainfactory hat es anstandslos funktioniert, auch bei mir in der lokalen Entwicklungsumgebung hatte ich keine Probleme.

Thema: Diverses, TYPO3 | Kommentare (1)

Infos zu Beruf „TYPO3 Entwickler“ auf FutureMe von XING

Geändert: Dienstag, 24. März 2015 | Erstellt: Samstag, 21. Februar 2015

XING hat mit FutureMe ein nette Spielerei mit allerlei Infos zu Berufen am Start. Wenn man dort nach dem Beruf „TYPO3 Entwickler“ sucht, bekommt man unter anderem die Information, dass ein TYPO3 Entwickler meist zwischen 32 und 37 Jahren alt ist und in Berlin lebt. Diese Infos hat XING hauptsächlich aus den Profilen seiner Mitglieder, aktuell werden dort bei der Suche nach „TYPO3 Entwickler“ über 4000 Mitglieder gefunden. Davon sind allerdings nur ein Bruchteil auf TYPO3 spezialisiert und tatsächlich TYPO3 Entwickler, es werden alle Mitglieder aufgelistet, die in ihrem Profil irgendwo „TYPO3“ und „Entwickler“ stehen haben.

Weiter ist zu lesen, dass eine der typischen Qualifikationen eines TYPO3 Entwicklers „Durchfluss“ ist:

Qualifikation „Durchfluss“

Auch ich habe selbstverständlich neben PHP und TypoScript tiefgreifende Erfahrungen an Durchfluss und stehe Ihnen als Berater in diesem Gebiet gerne zur Verfügung.
Spaß beiseite: Die Qualifikation „Durchfluss“ ist eine unglückliche Übersetzung aus dem englischen, eigentlich ist „Flow“ gemeint.

Interessant ist auch, dass ganze 12% der TYPO3 Entwickler in einem früheren Beruf Erzieher waren:

Gewöhnlicher Werdegang eines TYPO3 Entwicklers

Zuletzt habe ich mich noch gefreut, dass Weiden, mein derzeitiger Wohnort, als Ort mit besonders vielen TYPO3 Entwicklern in der Karte hervorgehoben wurde:

Orte mit besonders vielen TYPO3 Entwicklern

Mir ist aber nicht bekannt, dass hier weitere TYPO3 Entwickler arbeiten, weder eine Suche über XING noch über Google brachte TYPO3-Kollegen hervor.

Liebe Weidener Kollegen, meldet euch, dann organisieren wir einen Stammtisch!

Thema: Diverses, TYPO3 | Keine Kommentare

Fluid: Paginate Widget

Geändert: Mittwoch, 23. November 2016 | Erstellt: Freitag, 21. November 2014

Überschreiben der Sprachkeys

ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:fluid/Resources/Private/Language/locallang.xlf'][] = 'EXT:my_ext/Resources/Private/Language/locallang_fluid.xlf';

Mit _LOCAL_LANG in TypoScript kann man diese Sprachkeys nicht überschreiben. In der Datei locallang_fluid.xlf muss man nur die Sprachkeys aufnehmen, die man überschreiben möchte.

Achtung: Die neuen Sprachkeys gelten für alle Paginate Widgets, nicht nur für die in der Extension „my_ext“.

Eigenes Template

# Zentral für alle Extensions
config.tx_extbase.view.widget.TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper.templateRootPath = EXT:my_ext/Resources/Private/Templates/
# Nur für eine bestimmte Extension
plugin.tx_extension.view.widget.TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper.templateRootPath = EXT:my_ext/Resources/Private/Templates/

Dann muss man noch das Template aus Verzeichnis typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Widget/Paginate/ in Verzeichnis EXT:my_ext/Resources/Private/Templates/ViewHelpers/Widget/Paginate/ kopieren.

Pager nicht anzeigen bei nur einer Seite

Wenn es nur Items für eine Seite gibt, ist der Pager unnötig:

EXT:my_ext/Resources/Private/Templates/ViewHelper/Widget/Paginate/Index.html

<f:section name="paginator">
    <f:if condition="{pagination.numberOfPages} > 1">

Bootstrap Pagination

Angepasstes Template für Bootstrap (getbootstrap.com/components/#pagination).

EXT:my_ext/Resources/Private/Templates/ViewHelper/Widget/Paginate/Index.html

<f:if condition="{configuration.insertAbove}">
    <f:render section="paginator" arguments="{pagination: pagination, configuration: configuration}" />
</f:if>
 
<f:renderChildren arguments="{contentArguments}" />
 
<f:if condition="{configuration.insertBelow}">
    <f:render section="paginator" arguments="{pagination: pagination, configuration: configuration}" />
</f:if>
 
<f:section name="paginator">
    <f:if condition="{pagination.numberOfPages} > 1">
        <nav aria-label="Page navigation">
            <ul class="pagination">
                <li class="previous{f:if(condition: pagination.previousPage, else: ' disabled')}">
                    <f:if condition="{pagination.previousPage} > 1">
                        <f:then>
                            <f:widget.link addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}" arguments="{currentPage: pagination.previousPage}" additionalAttributes="{aria-label: '{f:translate(key: \"widget.pagination.previous\")}'}">
                                <span aria-hidden="true">&laquo;</span>
                            </f:widget.link>
                        </f:then>
                        <f:else>
                            <f:widget.link addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}" additionalAttributes="{aria-label: '{f:translate(key: \"widget.pagination.previous\")}'}">
                                <span aria-hidden="true">&laquo;</span>
                            </f:widget.link>
                        </f:else>
                    </f:if>
                </li>
                <f:if condition="{pagination.displayRangeStart} > 1">
                    <li>
                        <f:widget.link addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}">
                            1
                        </f:widget.link>
                    </li>
                </f:if>
                <f:if condition="{pagination.hasLessPages}">
                    <li class="disabled">
                        <span aria-hidden="true">...</span>
                    </li>
                </f:if>
                <f:for each="{pagination.pages}" as="page">
                    <f:if condition="{page.isCurrent}">
                        <f:then>
                            <li class="active">
                                <span>{page.number} <span class="sr-only">(current)</span></span>
                            </li>
                        </f:then>
                        <f:else>
                            <li>
                                <f:if condition="{page.number} > 1">
                                    <f:then>
                                        <f:widget.link addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}" arguments="{currentPage: page.number}">
                                            {page.number}
                                        </f:widget.link>
                                    </f:then>
                                    <f:else>
                                        <f:widget.link addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}">
                                            {page.number}
                                        </f:widget.link>
                                    </f:else>
                                </f:if>
                            </li>
                        </f:else>
                    </f:if>
                </f:for>
                <f:if condition="{pagination.hasMorePages}">
                    <li class="disabled">
                        <span aria-hidden="true">...</span>
                    </li>
                </f:if>
                <f:if condition="{pagination.displayRangeEnd} < {pagination.numberOfPages}">
                    <li>
                        <f:widget.link arguments="{currentPage: pagination.numberOfPages}" addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}">
                            {pagination.numberOfPages}
                        </f:widget.link>
                    </li>
                </f:if>
                <f:if condition="{pagination.nextPage}">
                    <li class="next{f:if(condition: pagination.nextPage, else: ' disabled')}">
                        <f:widget.link arguments="{currentPage: pagination.nextPage}" addQueryStringMethod="{configuration.addQueryStringMethod}" section="{configuration.section}" additionalAttributes="{aria-label: '{f:translate(key: \"widget.pagination.next\")}'}">
                            <span aria-hidden="true">&raquo;</span>
                        </f:widget.link>
                    </li>
                </f:if>
            </ul>
        </nav>
    </f:if>
</f:section>

 

Thema: TYPO3 | Keine Kommentare

TYPO3: Email layout of system extension „form“

Geändert: Mittwoch, 2. September 2015 | Erstellt: Freitag, 26. September 2014

After working in the past few years with the extensions powermail or formhandler when needing a form extension, I now wanted to give the system extension for forms, named „form“, a new chance. Until now, it looks good, even if the form wizard is a little bit buggy.

Form with extension "form"

Click to enlarge

In this article I want to show how you can adapt the layout of the email, which is sent after the form was submitted. You can see the form and it’s field in the image on the right side. Without modifications, the HTML version of the email looks like this:

HTML email

Especially the output of radio and checkbox groups do not look very nice and I do not like the spaces (around the whole text and around the radio/checkbox groups). Besides, the spaces (made with CSS rule „padding“) do not work in Outlook. But you have the possibility to change the layout with TypoScript:

TS Setup

tt_content.mailform.20 {
    postProcessor {
        mail {
            layout {
                label (
                    <labelvalue />
                )
                legend (
                    <legendvalue />
                )
                containerWrap (
                    <tbody>
                        <elements />
                    </tbody>
                )
                fieldset (
                    <td colspan="2">
                        <table cellspacing="0" cellpadding="0">
                            <legend />
                            <containerWrap />
                        </table>
                    </td>
                )
                checkbox (
                    <td width="200" valign="top">
                        <label />
                    </td>
                    <td>
                        <inputvalue />
                    </td>
                )
                radio (
                    <td width="200" valign="top">
                        <label />
                    </td>
                    <td>
                        <inputvalue />
                    </td>
                )
                radiogroup (
                    <td width="200" valign="top">
                        <legend />
                    </td>
                    <td>
                        <table cellspacing="0" cellpadding="0">
                            <containerWrap />
                        </table>
                    </td>
                )
                checkboxgroup < .radiogroup
                textline (
                    <td width="200" valign="top">
                        <label />
                    </td>
                    <td>
                        <inputvalue />
                    </td>
                )
                fileupload < .textline
                textarea (
                    <td width="200" valign="top">
                        <label />
                    </td>
                    <td>
                        <inputvalue />
                    </td>
                )
                select (
                    <td width="200" valign="top">
                        <label />
                    </td>
                    <td>
                        <elements />
                    </td>
                )
            }
        }
    }
}

Now the HTML email looks like this:

HTML email

Thema: TYPO3 Extensions | Keine Kommentare

Meine Erfahrungen mit Social Trading, im speziellen eToro

Geändert: Freitag, 15. Juli 2016 | Erstellt: Montag, 1. September 2014

Nachdem ich nun seit über einem Jahr bei eToro Geld angelegt habe, möchte ich hier meine Erfahrungen mitteilen. Über eToro findet man leider nicht viele Erfahrungsberichte im Internet. Was man findet, sind viele lieblos zusammengebaute Seiten bzw. zweifelhafte „Finanzportale“ mit „Testberichten“ über eToro, deren einziges Ziel es ist, eine Provision für Neuanmeldungen bei eToro zu kassieren (P.S.: Mein Affiliate-Link ist ganz unten auf der Seite ;)

Einen Überblick, was Social Trading ist, kann sich mit dem Artikel auf wikipedia verschaffen, oder direkt bei eToro. Auch die ARD berichtet über Social Trading und über eToro.

Hier nun die Vor- und Nachteile, die ich bei eToro sehe:

Pro eToro

  1. Gibt es seit 2007, Einlagensicherung bis 20000€, deutscher Support
  2. Man hat ein Demo-Konto mit dem man die Plattform und andere Trader testen kann, bevor man Echtgeld investiert.
  3. Das Demo-Konto steht zeitlich unbegrenzt zur Verfügung, im Gegensatz zu vielen Anbietern, bei denen das Demo-Konto nach wenigen Wochen oder Monaten deaktiviert wird und sie einen so zum Einsatz von Echtgeld zwingen möchten.
  4. Es ist spannend, über die Flash-Applikation im Browser oder über die App „in Echtzeit“ zu verfolgen, wie sich die Kurse bewegen und wie die Trader, die man kopiert, performen.
  5. eToro GebührenMan sieht, wie viele Gebühren man zahlen muss, bevor man einen Trade eröffnet. Man sieht auch, wie viele Gebühren bisher schon für einzelne Trades angefallen sind. Das ist wichtig, denn die Gebühren können durchaus die Höhe des investierten Betrages erreichen, wenn man diesen Trade sehr lange (z.B. 1 Jahr) offen hat oder einen hohen Hebel gewählt hat.
  6. Die Gebühren der Trades werden vom Betrag, den man dem Trader zugewiesen hat und den man kopiert, abgezogen. Das ist wichtig, um die echte Performance des Traders nachvollziehen zu können, denn viele Trader lassen verlustreiche Trades über Monate offen.
  7. Teilweise gibt es Promotions, bei denen man 10 bis 50% des überwiesenen Betrages zusätzlich gutgeschrieben bekommt.

Contra eToro

  1. Man handelt mit Dollar, d.h. eToro rechnet deine Euro-Überweisung mit einem relativ schlechten Wechselkurs in Dollar um. Als günstigste Variante hat sich für mich die Bezahlung in Dollar per Kreditkarte meiner Hausbank herausgestellt: Dort ist der Wechselkurs am besten, trotz der 1% Gebühren, die für Auslandszahlungen anfallen. Auch die Überweisung via PayPal war nicht günstiger.
  2. Oft erweitern Trader bei verlustreichen Trades den Stop Loss maßlos. Wenn man Glück hat und der Kurs sich erholt, wird der Trade dann ohne Verlust bzw. mit Gewinn geschlossen. Das kann aber auch bedeuten, dass der Trade dann monatelang offen ist, hohe Gebühren kostet und letztendlich doch mit einem sehr hohen Verlust geschlossen wird. Der Rekord bei mir war 2400% Verlust. Das bedeutet, wenn der Trader einen Trade über 10$ geöffnet hat, war der gesamte Verlust 240$ (zzgl. der Gebühren).
  3. eToro zeigt auf der Seite des Traders nicht den tatsächlichen Verlust an, sondern maximal 100%: Wenn z.B. ein Trader durch Erweiterung des Stop Loss auf einen Verlust >100% kommt (siehe z.B. vorherigen Punkt), zeigt eToro in den Statistiken (in der Historie über geschlossene Trades und als höchsten verlustreichen Trade) trotzdem nur 100% an. Die 2400% Verlust werden nirgendwo angezeigt.
  4. Fehlerhafte StatistikenOft sind die Statistiken des Traders fehlerhaft. Das ist eher keine Manipulation seitens eToro, sondern ein Bug, denn die falschen Statistiken kann man (meistens) eindeutig sehen, indem man die Statistiken über die vergangenen Zeiträume anschaut, die dann in keinster Weise übereinstimmen. Die fehlerhaften Statistiken gab es schon vor Monaten und aktuell immer noch, es ist schade, dass eToro das nicht in den Griff bekommt. Der Trader, zu dem diese fantastischen Statistiken gehören, hat in der letzten Woche tatsächlich einen Totalverlust eingefahren, in den vergangenen Wochen sogar mehrfach. Auch die 1,2 Mio. Prozent Gewinn in den letzten 24 Monaten stimmen absolut nicht.
  5. Im Personenfinder werden nur profitable Trader angezeigt. Könnte der Grund dafür sein, dass die meisten Trader auf der Plattform nur Verluste einfahren? Bei anderen Social Trading Plattformen, z.B. wikifolio, kann man sehen, wie das Verhältnis von Tradern mit Gewinn/Verlust ist.
  6. Früher konnte man den Trade eines Traders übernehmen durch Anpassung des Stop Loss bzw. des Take Profit. Das geht nun nicht mehr. Man kann einzelne Trades nur noch manuell schließen.
  7. Beim Ausbezahlen seines Geldes von eToro fällt eine Verwaltungsgebühr von 25$ an.
  8. Mein Gewinn seit August 2013 beträgt -75% (Stand September 2014)  – autsch! Obwohl ich meiner Meinung nach alles richtig gemacht habe: Ich habe 26 Trader kopiert, die in den letzten 12 Monaten gut performt haben. Leider haben mehrere Trader einen Totalverlust eingefahren, auch solche, deren Risiko als „gering“ eingestuft war. Mit 24 von 26 Tradern habe ich Verluste gemacht!
  9. Die meisten Trader, die ich kopiert habe, haben Verluste eingefahren, bis hin zum Totalverlust. Seit August 2013 habe ich insgesamt 37 Trader kopiert, das Verhältnis von den von mir kopierten Tradern mit Gewinn und mit Verlust beträgt 6:31 (Stand Juli 2016), die Mehrzahl hat also leider Verluste eingefahren.

Tipps zur Auswahl eines Traders

  1. Bei der Wahl der Trader, die man kopiert, sollte man darauf achten, dass der Trader schon mehrere Monate bzw. Jahre tradet und ein kontinuerliches Wachstum vorweist.
  2. Der Trader sollte möglichst keine seit Monaten offenen Positionen haben. Ein Trader sollte den „Mut“ haben, verlustreiche Positionen zu schließen. Ansonsten summiert sich der Verlust der offenen Positionen und die Gebühren so weit, dass man das gesamte, dem Trader zugewiesene, Guthaben verliert.
  3. Der Trader sollte bei einem verlustreichen Trade nicht mehr als 100% des Einsatzes verlieren. Das sieht man leider nicht in den Statistiken des Traders, dafür muss man den Trader (im Demokonto) kopieren und beobachten.
  4. Der Trader sollte selbst traden, nicht (ausschließlich) andere Trader kopieren. Ansonsten kann es passieren, dass man tief ins Minus rutscht, weil ein einziger Trader schlecht handelt und alle anderen Trader ihn kopiert haben.

Trader, die ich empfehlen kann

  1. An erster Stelle steht eindeutig 4exPirate: Dieser Trader ist sehr vorsichtig und öffnet nur sehr wenige Trades, manchmal nur einen pro Woche, aber diese schließt er dann meistens mit Gewinn. Wenn der Trade verlustreich ist, schließt er ihn frühzeitig, manchmal bei -20%, ansonsten bei maximal -100%.
  2. Dann möchte ich noch Malsolo, caraj51 und hexcho2 erwähnen, diese Trader handeln eher vorsichtig und weisen eine positive Bilanz aus.
    Update 21.03.2016: Aktuell kann ich diese Trader empfehlen: Venom09, sameerah786, Running-Chris und Dimitrios1. Diese traden eher vorsichtig.

Wenn du den Erfahrungsbericht hilfreich fandest und dich bei eToro anmelden möchtest, nutze bitte diesen Link, dann bekommst du 50$ Startguthaben und ich bekomme ggf. eine Provision*:

Bei eToro anmelden

* Meine Provision beträgt 100$, wenn du das erste Mal 100$ an eToro überwiesen hast.

Thema: Anlagestrategie | Kommentare (9)

Fluid: Blätterfunktion ohne Widget „paginate“

Geändert: Dienstag, 11. Oktober 2016 | Erstellt: Freitag, 18. Juli 2014

Wie man das Widget „paginate“ nutzt, kann man unter anderem auf typo3blogger.de nachlesen. Wenn man dieses Widget aber nicht einsetzen kann, z.B. weil man die Datenbankabfrage im Repository mit

$query->statement("SELECT * FROM...");

erzeugt, muss man den Pager selbst erzeugen, hier eine mögliche Vorgehensweise:

Pager-Array generieren

EXT:myExt/Classes/Controller/MyController.php

/**
 * action list
 *
 * @param integer $page: paginator, starts with 0
 * @return void
 */
public function listAction($page = 0) {
    $page = (int)$page;
    $this->view->assign('page', $page);
    $myRecords = $this->objectManager->get(\Vendor\MyExt\Domain\Repository\MyRepository::class)->myQuery();
    $this->view->assign('myRecords', $myRecords);
    // generate pager
    if($myRecords->count()) {
        $paginate = array();
        for($i = 0; $i < $myRecords->count(); $i += (int)$this->settings['pager']['itemsPerPage']) {
            $paginate[] = $i;
        }
        $this->view->assign('paginate', $paginate);
    }
}

TypoScript Setup für Berechnungen in Fluid

Für den Pager werden im Fluid Template Berechnungen durchgeführt. Da Fluid selbst keine Berechnungen durchführen kann, wird dies über TypoScript erledigt.

EXT:myExt/Configuration/TypoScript/setup.txt

plugin.tx_myext {
    math = TEXT
    math {
        current = 1
        prioriCalc = 1
    }
}

Pager als Partial

EXT:myExt/Resources/Private/Partials/Pager/Pager.html

<f:if condition="{paginate->f:count()} > 1">
    <f:alias map="{
        paginateMax:  '{f:cObject(typoscriptObjectPath: \'plugin.tx_myext.math\', data: \'{paginate->f:count()}-1\')}',
        paginatePrev: '{f:cObject(typoscriptObjectPath: \'plugin.tx_myext.math\', data: \'{currentPage}-1\')}',
        paginateNext: '{f:cObject(typoscriptObjectPath: \'plugin.tx_myext.math\', data: \'{currentPage}+1\')}'
        }">
        <ul class="tx_myext-list-browse">
            <f:if condition="{currentPage} > 0">
                <li class="first">
                    <f:link.action addQueryString="1" arguments="{page: '0'}">
                        &lt;&lt;
                    </f:link.action>
                </li>
                <li class="prev">
                    <f:link.action addQueryString="1" arguments="{page: paginatePrev}">
                        &lt;
                    </f:link.action>
                </li>
            </f:if>
            <f:for each="{paginate}" as="paginateItem" key="p" iteration="i">
                <li>
                    <f:link.action addQueryString="1" arguments="{page: p}" class="{f:if(condition: '{p} == {currentPage}', then: 'active')}">
                        {i.cycle}
                    </f:link.action>
                </li>
            </f:for>
            <f:if condition="{currentPage} < {paginateMax}">
                <li class="next">
                    <f:link.action addQueryString="1" arguments="{page: paginateNext}">
                        &gt;
                    </f:link.action>
                </li>
                <li class="last">
                    <f:link.action addQueryString="1" arguments="{page: paginateMax}">
                        &gt;&gt;
                    </f:link.action>
                </li>
            </f:if>
        </ul>
    </f:alias>
</f:if>

Einbindung des Partials im Template

Im Template wird der Pager eingebunden und nur die Datensätze der gewählten Seite ausgegeben.

EXT:myExt/Resources/Private/Templates/MyController/List.html

<f:if condition="{myRecords}">
    <f:render partial="Pager/Pager" arguments="{paginate:paginate, currentPage:page}" />
    <f:for each="{myRecords}" as="myRecord" iteration="i">
        <f:if condition="{i.index} >= {f:cObject(typoscriptObjectPath: 'plugin.tx_myext.math', data: '{page}*{settings.pager.itemsPerPage}')}">
            <f:if condition="{i.index} < {f:cObject(typoscriptObjectPath: 'plugin.tx_myext.math', data: '({page}+1)*{settings.pager.itemsPerPage}')}">
                Record UID: {myRecord.uid}
            </f:if>
        </f:if>
    </f:for>
</f:if>

 

Thema: TYPO3 Extension-Programmierung | Keine Kommentare

Hintergrundbilder im Slider

Geändert: Mittwoch, 2. Juli 2014 | Erstellt: Donnerstag, 26. Juni 2014

In diesem Artikel möchte ich zeigen, wie man (Hintergrund)Bilder in einem Slider verwenden kann. Es gibt zwar einige Bilder-Slider, bei diesen kann man aber meistens nur Bilder durchblättern. Oft ist aber gewünscht, dass über dem Bild noch eine Überschrift Links oder sonstiger Text steht, also Inhalte, für die man die Standard Inhaltselemente von TYPO3 nutzen kann. Gut dafür geeignet ist die oft genutzte Erweiterung jfmulticontent oder aber die Umsetzung mit Ext. gridelements. Bei beiden Varianten können alle TYPO3 Inhaltselemente (Text, Bild, Text mit Bild, Formulare, Plugins, …) im Slider verwendet werden. Und mit meiner Erweiterung backgroundimage4ce kann man für alle Inhaltselemente Hintergrundbilder angeben. Screenshots, wie die Bedienung im TYPO3 Backend erfolgt, die Ausgabe im Frontend, eine Anleitung zur Installation und vieles mehr findet man im Handbuch von Ext. backgroundimage4ce.

Anstatt der „langweiligen“, klassischen Darstellung und Bedienung des Sliders gibt es hierbei viele weitere Möglichkeiten: Man kann zum Beispiel die Hintergrundbilder „supersized“, also verbreitert auf die gesamte Bildschirmbreite und/oder -höhe, darstellen und hinter dem gesamten Seiteninhalt durchscrollen. Oder man verwendet andere Effekte: Anstatt die Inhalte klassisch von rechts nach links durchzusliden, kann man diese zum Beispiel auch überblenden.

Auf diesen Seiten sieht man eine Demonstration des Sliders:

  1. Kombination von backgroundimage4ce mit gridelements: www.datacollect.com
  2. Kombination von backgroundimage4ce mit jfmulticontent: www.spezialitaetenland-bayern.de

Setzt du bei einer Webseite auch diese Kombination für einen Slider ein? Falls ja, nehme ich diese gerne in die Liste auf. Oder kennst du eine andere Möglichkeit für einen Slider in TYPO3, bei dem Text über einem Bild durchgeblättert werden kann?

Thema: TYPO3 Extensions | Keine Kommentare

TYPO3: BE Modul mit persistenten Menü

Erstellt: Freitag, 16. Mai 2014

Wie ein Backend Modul mit Extbase/Fluid erstellt und dort auch ein Menü anbietet, kann man in diesem Artikel nachlesen.

Damit dieses Menü sich nun aber den zuvor ausgewählten Menüpunkt merkt, auch wenn man zwischenzeitlich in einem anderen BE Modul war oder im Seitenbaum klickt, muss man den letzten Menüstatus für den Backend-User abspeichern und beim Aufrufen des BE Moduls prüfen, ob dieser gesetzt ist und ggf. auf ihn weiterleiten:

namespace TYPO3\MyExt\Controller;
class BackendController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
 
    /**
     * Redirect to the saved menu item
     */
    protected function initializeAction() {
        $vars = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('tx_myext_web_myexttxmyextm1');
        // redirect only, if no menu item has been selected and if the last selection has been saved
        $lastActionMenuItem = $GLOBALS['BE_USER']->uc['my_ext']['lastActionMenuItem'];
        if(!$vars['action'] && $lastActionMenuItem) {
            // one redirect is enough
            self::saveState();
            // redirect
            $this->redirect($lastActionMenuItem);
        }
    }
 
    public function indexAction() {
        // save selected menu item
        self::saveState('index');
    }
 
    /**
     * Save the selected menu item
     *
     * @param string $actionMenuItem
     * @return void
     */
    protected static function saveState($actionMenuItem = '') {
        $GLOBALS['BE_USER']->uc['my_ext']['lastActionMenuItem'] = $actionMenuItem;
        $GLOBALS['BE_USER']->writeUC();
    }
}

Die genaue Schreibweise des GET-Parameters „tx_myext_web_myexttxmyextm1“ findet man am leichtesten heraus, indem man sich die Adresse des Iframes des BE Moduls anzeigen lässt. Der Platzhalter „my_ext“ ist der Extension-Key, „MyExt“ ist der Extension-Key in CamelCase Schreibweise.

Abgeschaut bei System-Extension „reports“.

Thema: TYPO3 Extension-Programmierung | Keine Kommentare