Categorie archief: Geen categorie

WordPress ontwikkelomgeving op Mac met Brew, Nginx, PHP 5.6, PHP-FPM, MariaDB, phpMyAdmin en meer

 In dit bericht beschrijf ik in een aantal stappen hoe je een WordPress ontwikkelomgeving omgeving kunt opzetten op een Mac.

Brew

Homebrew is een pakket manager voor je Mac en erg handig voor het installeren van allerlei handig tools.

http://brew.sh/

Met het volgende commando kun je Homebrew installeren, maar ik adviseer je om de instructies op de Homebrew website te volgen:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Mocht je Brew al geïnstalleerd hebben dan kun je met het volgende commando Brew bijwerken.

brew update
brew upgrade

PHP

PHP kan eenvoudig via Homebrew geïnstalleerd worden, maar hiervoor moet je wel even de PHP repository intappen.

https://github.com/Homebrew/homebrew-php

Met de volgende commando’s kun je de PHP repository voor Homebrew tappen:

brew tap homebrew/dupes
brew tap homebrew/versions
brew tap homebrew/homebrew-php

Vervolgens kun je met het volgende commando bekijken wel opties er beschikbaar zijn voor het installeren van PHP 5.6:

brew options php56

Als het goed is geeft dit commando het volgende resultaat:

--disable-opcache
	Build without Opcache extension
--disable-zend-multibyte
	Disable auto-detection of Unicode encoded scripts (PHP 5.2 and 5.3 only)
--homebrew-apxs
	Build against apxs in Homebrew prefix
--with-apache
	Enable building of shared Apache 2.0 Handler module, overriding any options which disable apache
--with-cgi
	Enable building of the CGI executable (implies --without-apache)
--with-debug
	Compile with debugging symbols
--with-fpm
	Enable building of the fpm SAPI executable (implies --without-apache)
--with-gmp
	Build with gmp support
--with-homebrew-curl
	Include Curl support via Homebrew
--with-homebrew-libxslt
	Include LibXSLT support via Homebrew
--with-homebrew-openssl
	Include OpenSSL support via Homebrew
--with-imap
	Include IMAP extension
--with-libmysql
	Include (old-style) libmysql support instead of mysqlnd
--with-mssql
	Include MSSQL-DB support
--with-pdo-oci
	Include Oracle databases (requries ORACLE_HOME be set)
--with-pgsql
	Include PostgreSQL support
--with-phpdbg
	Enable building of the phpdbg SAPI executable (PHP 5.4 and above)
--with-thread-safety
	Build with thread safety
--with-tidy
	Include Tidy support
--without-bz2
	Build without bz2 support
--without-mysql
	Remove MySQL/MariaDB support
--without-pcntl
	Build without Process Control support
--without-pear
	Build without PEAR
--without-snmp
	Build without SNMP support
--HEAD
	install HEAD version

Ik heb vervolgens PHP 5.6 geïnstalleerd met de volgende opties:

brew install php56 --with-debug --with-fpm --with-homebrew-curl --with-homebrew-libxslt --with-homebrew-openssl

Zodra de installatie is voltooid kun je via het volgende commando controleren of de juiste PHP versie is geïnstalleerd;

php -v

Vervolgens kun je met het volgende commando controleren welke modules er actief zijn:

php -m

PHP-extensies

Er zijn binnen Brew flink wat PHP-extensies beschikbaar, deze kun je met het volgende commando weergeven:

brew search php56-

Hieronder vind je een aantal handige PHP-extensies ik geïnstalleerd heb.

Xdebug

Xdebug is een PHP-extensie die debugging functionaliteiten toevoegt, om dit te installeren kan het volgende commando uitgevoerd worden:

brew install php56-xdebug

Tidy

brew install php56-tidy

PHP-FPM

Om PHP-FPM op te starten dienen de volgende commando’s uitgevoerd te worden:

ln -sfv /usr/local/opt/php56/*.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.php56.plist

Met behulp van het volgende commando kan vervolgens bekeken worden of PHP-FPM luistert naar poort 9000.

lsof -Pni4 | grep LISTEN | grep php

MariaDB

Ook MariaDB kan via Homebrew geïnstalleerd worden met behulp van het volgende commando:

brew install mariadb

Als het goed is gaat Homebrew vervolgens MariaDB installeren en vermeld het de volgende kanttekeningen:

To have launchd start mariadb at login:
    ln -sfv /usr/local/opt/mariadb/*.plist ~/Library/LaunchAgents
Then to load mariadb now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
Or, if you don't want/need launchctl, you can just run:
    mysql.server start

Aangezien MariaDB van mij opgestart mag worden bij het inloggen heb ik vervolgens het volgende commando uitgevoerd:

ln -sfv /usr/local/opt/mariadb/*.plist ~/Library/LaunchAgents

Om MariaDB na installatie op te starten heb ik het volgende commando uitgevoerd:

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist

Om de MySQL installatie te beveiligen kan het volgende commando uitgevoerd worden:

mysql_secure_installation

Mocht je je root wachtwoord vergeten zijn dan kun je de volgende pagina van MariaDB volgen: https://mariadb.com/blog/how-reset-root-password-mariadb-linux.

Mocht je eerder al MySQL geïnstalleerd hebben dan kun je via de volgende stappen MySQL verwijderen: http://stackoverflow.com/questions/1436425/how-do-you-uninstall-mysql-from-mac-os-x.

phpMyAdmin

Voor het installeren van phpMyAdmin kan het volgende commando uitgevoerd worden:

brew install phpmyadmin

Na de installatie zal Homebrew de volgende kanttekeningen melden:

Note that this formula will NOT install mysql. It is not
required since you might want to get connected to a remote
database server.

Webserver configuration example (add this at the end of
your /etc/apache2/httpd.conf for instance) :
  Alias /phpmyadmin /usr/local/share/phpmyadmin
  
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
  
Then, open http://localhost/phpmyadmin

More documentation : file:///usr/local/Cellar/phpmyadmin/4.2.8/share/phpmyadmin/doc/

Configuration has been copied to /usr/local/etc/phpmyadmin.config.inc.php
Don't forget to:
  - change your secret blowfish
  - uncomment the configuration lines (pma, pmapass ...)

Apache uitschakelen

Binnen een Mac wordt Apache vaak standaard opgestart, met het volgende commando kan Apache uitgeschakeld worden:

sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist

Bron: http://stackoverflow.com/a/20439859

Nginx

Nginx kan geïnstalleerd worden met het volgende commando:

brew install nginx

Na de installatie zal Homebrew de volgende kanttekeningen melden:

Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

To have launchd start nginx at login:
    ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents
Then to load nginx now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
Or, if you don't want/need launchctl, you can just run:
    nginx

Na installatie zal er een standaard Nginx configuratie bestand ingesteld zijn. Aangezien in dit bestand veel commentaar staat is het niet heel overzichtelijk. Daarom verwijderen we dit bestand volledig en voegen we een eigen configuratie bestand toe.

rm /usr/local/etc/nginx/nginx.conf
nano /usr/local/etc/nginx/nginx.conf

In het nieuwe configuratie bestand plaatsen we het volgende:

worker_processes  1;
 
error_log  /usr/local/etc/nginx/logs/error.log debug;
 
events {
    worker_connections  256;
}
 
http {
    include             mime.types;
    default_type        application/octet-stream;
 
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
    access_log  /usr/local/etc/nginx/logs/access.log  main;
 
    sendfile            on;
 
    keepalive_timeout   65;
 
    index index.html index.php;
 
    include /usr/local/etc/nginx/sites-enabled/*; 
}

Op de Nginx documentatie websites staat meer informatie over de verschillende directives:

Voor de logs en configuratie bestanden maken we een aantal maken aan:

mkdir -p /usr/local/etc/nginx/logs
mkdir -p /usr/local/etc/nginx/sites-available
mkdir -p /usr/local/etc/nginx/sites-enabled
mkdir -p /usr/local/etc/nginx/conf.d

Composer

brew install composer

WP-CLI

brew install wp-cli

 

Dnsmasq

Met behulp van Dnsmasq kunnen we er voor zorgen dat elk request naar bijvoorbeeld .dev domeinnamen doorverwezen worden naar je lokale IP-adres 127.0.0.1. Hiermee hoef je dus niet voor elke ontwikkelomgeving een extra regel toe te voegen aan je host bestand (/etc/hosts).

brew install dnsmasq

Na het installeren van Dnsmasq geeft Brew de volgende kanttekeningen:

To configure dnsmasq, copy the example configuration to /usr/local/etc/dnsmasq.conf
and edit to taste.

  cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf

To have launchd start dnsmasq at startup:
    sudo cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
Then to load dnsmasq now:
    sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

t

Bronnen

Website controleren op virus

Veel website ontwikkelaars zullen wel eens een website in beheer hebben gehad die geïnfecteerd is geraakt met een virus. Na het opschonen van een website kan met online tools gecontroleerd worden of de website nog gemarkeerd wordt als onveilig of geïnfecteerd. Een aantal populaire online tools zijn:

 

PHP CodeSniffer en WordPress Coding Standards

Als WordPress ontwikkelaar volg ik ook graag de WordPress Coding Standards in de WordPress plugins en thema’s die ik ontwikkel. Ook bij Pronamic, het bedrijf waar ik voor werk, volgen we strikt deze standaarden. Sinds kort gebruik ik PHP CodeSniffer en de WordPress Coding Standards sniffs om projecten te controleren op de WordPress Coding Standards.

Op een Mac kan met behulp van Brew eenvoudig de PHP CodeSniffer package geïnstalleerd worden. Hiervoor kan de volgende commando in de Terminal uitgevoerd worden:

$ brew install php-code-sniffer

Als de installatie is voltooid kan met de volgende commando gecontroleerd worden welke versie van PHP CodeSniffer is geïnstalleerd.

$ phpcs --version
PHP_CodeSniffer version 1.5.2 (stable) by Squiz (http://www.squiz.net)

Vervolgens kan met het volgende commando gecontroleerd worden welke PHP CodeSniffer standaarden zijn geïnstalleerd.

$ phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend

Standaard worden de WordPress Coding Standards sniffs niet meegeleverd in de PHP CodeSniffer package. De WordPress Coding Standards zijn echter eenvoudig te installeren via de volgende commando:

$ git clone git://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git /usr/local/Cellar/php-code-sniffer/1.5.2/CodeSniffer/Standards/WordPress

Als goed is staat hierna “WordPress” tussen de lijst met de geïnstalleerde PHP CodeSniffer standaarden.

$ phpcs -i
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, WordPress and Zend

Standaard zal er gebruik gemaakt worden van de WordPress Coding Standards in de ‘master’ branche. De ‘develop’ branche is echter veel interessanter, daarom is het interessant om over te schakelen naar de de ‘develop’ branche. Hiervoor kunnen de volgende commando’s uitgevoerd worden:

$ cd /usr/local/Cellar/php-code-sniffer/1.5.2/CodeSniffer/Standards/WordPress
$ git checkout develop

Hierna kan een WordPress thema of plugin met de volgende commando gecontroleerd worden op de WordPress Coding Standards:

$ phpcs -p -s -v --standard=WordPress .

Zelf maak ik veel gebruik van Grunt om ontwikkel taken verder te automatiseren. Er is een Grunt PHP CodeSniffer taak beschikbaar die hierbij van pas komt. Deze taak kan met de volgende commando geïnstalleerd worden.

$ npm install grunt-phpcs --save-dev

Binnen de Pronamic iDEAL plugin is te zien hoe we ‘phpcs’ Grunt taak verder hebben geconfigureerd. We gebruiken daar ook een “project.ruleset.xml” bestand om een aantal mappen/bestanden en sniffs uit te schakelen.

Pronamic iDEAL – OmniKassa conflict met Yoast SSL tip

Vandaag heb ik een probleem onderzocht waarbij de betalingsstatus updates van de OmniKassa niet binnen kwamen op de WordPress omgeving. Hierdoor werd de status van de betaling niet bijgewerkt en in het geval van WooCommerce de status van de bestelling ook niet. Al snel bleek dat dit probleem beperkt was tot de specifieke WordPress installatie van een Pronamic iDEAL gebruiker. Na wat debug werk bleek een SSL-forceer script van Yoast voor een conflict te zorgen.

Binnen de Pronamic iDEAL plugin wordt ingehaakt op de WordPress ‘template_redirect’ actie om te luisteren naar OmniKassa betalingsstatus requests:

https://github.com/pronamic/wp-pronamic-ideal/blob/2.4.3/classes/Pronamic/WordPress/IDeal/Plugin.php#L86

De luisterfunctie van de Pronamic iDEAL plugin haakt in op de ‘template_redirect’ actie met de standaard prioriteit van 10. Yoast zijn SSL-forceer functie wordt in zijn voorbeeld toegevoegd met prioriteit van 1. Hierdoor zal Yoast zijn functie altijd voor de Pronamic iDEAL plugin uitgevoerd worden. Doordat Yoast in zijn functie een HTTP-redirect header verstuurd en vervolgens het script stopt met een exit(); aanroep zal de Pronamic iDEAL luisterfunctie nooit uitgevoerd worden.

Door Yoast zijn doorverwijzing naar een https:// URL zal de OmniKassa POST-data niet meegestuurd worden. Hierdoor zal de betalingsstatus update van de OmniKassa dus nooit de Pronamic iDEAL plugin bereiken.

Om dit conflict op te lossen hebben we de Pronamic iDEAL pluign aangepast zodat deze niet langer de ‘template_redirect’ actie gebruikt om te luisteren naar betalingsstatus updates. In plaats daarvan gebruiken we nu de ‘wp_loaded’ actie.

De ‘wp_loaded’ actie wordt eerder uitgevoerd dan de ‘template_redirect’ actie, hierdoor krijgt de Pronamic iDEAL plugin voorrang op de SSL-forceer functie van Yoast. Ook is de ‘wp_loaded’ functie waarschijnlijk geschikter voor het luisteren naar betalingsstatus updates. De ‘template_redirect’ functie is waarschijnlijk ook meer bedoeld voor thema/templates gerelateerde doorverwijzingen. In de volgende commit is de aanpassing terug te zien:

https://github.com/pronamic/wp-pronamic-ideal/commit/0e6633bb1fe024e3566fcc91955f2dcc9fe17809

WordPress oEmbed en de Vimeo API (Froogaloop)

De videoplayer van Vimeo kan met behulp van JavaScript aangestuurd worden. Op de JavaScript API pagina van Vimeo is hier meer informatie over te vinden. Ook is de kleine JavaScript bibliotheek Froogaloop erg handig om hiervoor te gebruiken.

Om gebruik van te maken van de Vimeo JavaScript API moet echter de embed code aangepast worden. Ze moet de video van de URL in de iframe uitgebreid worden met een ‘api’ parameter.

http://player.vimeo.com/video/VIDEO_ID?api=1

Als je meerdere URL’s op 1 pagina hebt ingevoerd moet daar ook nog een ‘player_id’ parameter aan toegevoegd worden:

http://player.vimeo.com/video/VIDEO_ID?api=1&player_id=vimeoplayer

Helaas ondersteund WordPress en Vimeo oEmbed deze parameters nog niet. Dit is echter eenvoudig te corrigeren met behulp van de volgende fiter functies. Met behulp van de eerste filter voegen we de ‘api’ en ‘player_id’ parameter toe aan de video URL:

In de tweede filter functie zorgen we dat het ‘iframe’ element dezelfde ‘id’ attribuut krijgt als de ‘player_id':

Vervolgens kunnen we de volgende shortcode gebruiken om gebruik te maken van WordPress oEmbed en de Vimeo API en player ID:

[embed player_id="uniqid"]http://vimeo.com/31215588[/embed]

Van fouten kun je veel leren

Een paar weken geleden kwam ik het blog bericht “Mistakes I’ve Made (And Lessons Learned Along The Way)” van op Smashing Magazine tegen. In zijn blog schrijft hij over fouten die hij gemaakt heeft en wat hij daar van geleerd heeft. Ik denk dat veel van deze fouten worden gemaakt door bedrijven. Voor mij als ontwikkelaar bij Pronamic daarom ook zeker een leerzaam bericht.

Fout #1: Voortgang belangrijker vinden dan projecten (en personen)

Jeremy verteld in zijn blog over een project waarbij hij minder goed kon opschieten met de opdrachtgever. Om het project wel in goede banen te leiden hield hij zich vast aan een proces. Dit kwam de samenwerking met de opdrachtgever echter niet ten goede.

Fout #2: Vertellen in plaats van laten zien

Veel bedrijven vertellen hoe fantastisch hun product en/of dienst is. Dit terwijl iedereen het spreekwoord “Praatjes vullen geen gaatjes” kent. Door klanten niet te laten zien hoe het product kunnen er verkeerde verwachtingen ontstaan. Dit is eenvoudig te voorkomen door het product of dienst te laten zien.

Jermey behandeld in zijn blog bericht nog een 3-tal fouten waarvan hij geleerd heeft:http://www.smashingmagazine.com/2013/07/26/mistakes-made-lessons-learned/

Een succesvolle Git vertakking model

Op mijn werk bij Pronamic maken we al enige tijd gebruik van Git voor het bijhouden van ontwikkelingen in een versiebeheersysteem. We werkten hierbij voornamelijk met één tak, de ‘master’ branch. Sinds ons team echter is versterk met een extra ontwikkelaar bleek dit echter niet altijd meer even handig te werken. Collega Leon stelde daarom voor om te gaan werken volgens het branching model van Vincent Driessen.

Vicent heeft een eenvoudige en logische manier van vertakken binnen Git in kaart gebracht. Hieronder is een mooi overzicht te zien van hoe het vertakken in de praktijk gebruikt kan worden:

Git branche model

 

Twinfield factuur sjabloon wijzigen in LibreOffice (OpenOffice)

Binnen Twinfield kunnen facturen gemaakt worden op basis van Word sjabloon. Deze sjablonen kunnen eenvoudig met behulp van Word gewijzigd worden. In de volgende YouTube video is te zien hoe dit gerealiseerd kan worden:

We maken bij Pronamic echter geen gebruik van Word, maar van OpenOffice en/of LibreOffice. Als we de sjablonen met deze programma’s wijzigden dan ontstonden er helaas problemen. Hierdoor konden we bij Pronamic de Twinfield factuur sjablonen helaas niet wijzigen.

In de Twinfield Knowledge Base staan verschillende voorbeelden van hoe een factuur sjabloon er uit moet zien:

  • Hoe maak ik een Word-factuur, een aanmaning of een betaalspecificatie?
  • How do I create a Word-invoice, a dunning or a payment specification?

Nederlandse sjablonen

Bestand Grootte Laatst gewijzigd
uitleg_Word_sjabloon.doc 123KB 06/08/2012 13:18
sjabloon-NL-FactuurExclBTW-4.1.docx 15KB 16/07/2012 13:48
sjabloon-NL-TimePlus-1.2.dot 48KB 30/06/2011 13:12
sjabloon-NL-Time-1.3.dot 45KB 30/06/2011 13:12
sjabloon-NL-FactuurInclBTW-4.1.dot 47KB 30/06/2011 13:12
sjabloon-NL-BetalenIncasseren-1.2.dot 35KB 30/06/2011 13:11
sjabloon-NL-Aanmaning-1.6.dot 37KB 30/06/2011 13:10

Engelse sjablonen

Bestand Grootte Laatst gewijzigd
ChequeTemplate.doc 46KB 27/09/2012 12:21
explanation_Word_template.doc 126KB 06/08/2012 13:20
template-EN-TimePlus-1.3.dot 58KB 30/06/2011 16:42
template-EN-Time-1.4.dot 47KB 30/06/2011 16:41
template-EN-PayCollect-1.2.dot 36KB 30/06/2011 16:41
template-EN-Invoice-VatIncl-4.1.dot 46KB 30/06/2011 16:40
template-EN-Invoice-VatExcl-4.1.dot 46KB 30/06/2011 16:39
template-EN-Dunning-1.6.dot 36KB 30/06/2011 16:39

In het uitleg document van Twinfield wordt aangegeven dat de volgende samenvoeg velden beschikbaar zijn:

HeaderStart
HeaderEnd
FooterStart
FooterEnd
addressinv_name
addressinv_addr1
addressinv_addr2
addressinv_addr3
addressinv_postcode
addressinv_city
addressinv_country_@code
addressinv_country
addressinv_addr4
addressinv_addr5
addressdel_name
addressdel_addr1
addressdel_addr2
addressdel_addr3
addressdel_postcode
addressdel_city
addressdel_country_@code
addressdel_country
addressdel_addr4
addressdel_addr5
header_invdate
header_duedate
header_perfdate
header_invnum
header_vatnumber
header_customer
header_customername
header_period
header_headerdescr
header_footerdescr
header_printstatus
header_paycode
bank_name
bank_account
header_print
header_printcount
header_usrcode_@name
header_authoriser_@name
TableStart:lines
TableEnd:lines
lines_line_@id
header_currency
lines_line_artcode
lines_line_subcode
lines_line_name
lines_line_sname
lines_line_extref1
lines_line_extref2
lines_line_extref3
lines_line_dim2
lines_line_dim2_@name
lines_line_dim3
lines_line_dim3_@name
lines_line_dim4
lines_line_dim4_@name
lines_line_fincode
lines_line_finnumber
lines_line_acpay_@name
lines_line_perfdate
lines_line_qty
lines_line_descr
lines_line_unitsprice_@regional
lines_line_unitspriceinc_@regional
lines_line_currency
lines_line_taxrate
lines_line_taxvalue_@regional
lines_line_invvalue_@regional
lines_line_invvalueinc_@regional
TableStart:taxlines
TableEnd:taxlines
calclines_taxline_currency
calclines_taxline_taxname
calclines_taxline_perftype
calclines_taxline_perfyearmonth
calclines_taxline_taxover_@regional
calclines_taxline_taxvalue_@regional
calclines_taxline_valueincl_@regional
calclines_totalline_valueexcl_@regional
calclines_totalline_taxvalue_@regional
calclines_totalline_value_@regional
lines_line_teq_week
lines_line_teq_month
lines_line_teq_quarter
lines_line_dim1
lines_line_dim1_@name
lines_line_dim1_@sname
lines_line_dim1_@prjinvdescr
lines_line_dim2_@sname
lines_line_dim2_@prjinvdescr
lines_line_transdate
TableStart:timelines
TableEnd:timelines
time_line_user_@name
time_line_user_@sname
time_line_user
time_line_transdate
time_line_project_@name
time_line_project_@sname
time_line_project_@prjinvdescr
time_line_project
time_line_activity_@name
time_line_activity_@sname
time_line_activity_@actinvdescr
time_line_activity
time_line_descr
time_line_qty
time_line_price
calclines_totalline_value_@predecimal
calclines_totalline_value_@postdecimal
header_customer_@account
customer_custname
customer_name
customer_addr1
customer_addr2
customer_addr3
customer_postcode
customer_city
customer_country
customer_country_@name
customer_modified
customer_dimcode
customer_basecurrency
customer_basecurrency_@name
customer_basecurrency_@shortname
customer_reportingcurrency
customer_reportingcurrency_@name
customer_reportingcurrency_@shortname
customer_invoicecurrency
customer_invoicecurrency_@name
customer_invoicecurrency_@shortname
customer_totalbasevalueopen
customer_totalrepvalueopen
customer_totalvalueopen
TableStart:customer
TableEnd:customer
customer_detail_invnumber
customer_detail_inpdate
customer_detail_basevalueopen
customer_detail_valueopen
customer_detail_repvalueopen
customer_detail_basevalue
customer_detail_value
customer_detail_repvalue
customer_detail_basevaluepaid
customer_detail_valuepaid
customer_detail_repvaluepaid
customer_detail_days
customer_detail_duedate
customer_detail_currency
customer_detail_currency_@name
customer_detail_currency_@shortname
customer_detail_description
customer_totalbasevalueopen_@predecimal
customer_totalrepvalueopen_@predecimal
customer_totalvalueopen_@predecimal
customer_totalbasevalueopen_@postdecimal
customer_totalrepvalueopen_@postdecimal
customer_totalvalueopen_@postdecimal
customer_account
name
addr1
addr2
addr3
addr4
addr5
postcode
city
country
dimcode
dimname
date
office_code
office_name
office_vatnumber
office_address_line1
office_address_line2
office_address_line3
office_address_line4
office_address_line5
office_address_line6
office_address_zipcode
office_address_city
office_address_country
office_address_telephone
office_address_fax
bank_code
bank_ascription
bank_iban
bank_accountnumber
bank_nationalbic
bank_bic
bank_address_line1
bank_address_line2
bank_address_line3
bank_address_line4
bank_address_line5
bank_address_line6
bank_address_zipcode
bank_address_city
bank_address_country
bank_address_telephone
bank_address_fax
TableStart:details
TableEnd:details
details_detail_invdate
details_detail_duedate
details_detail_invnumber
details_detail_origvalue
details_detail_value
details_detail_origbasevalue
details_detail_basevalue
details_detail_trscode_@name
details_detail_trsnumber
origvalue
value
currency
valuetext
TableStart:cheque_details
TableEnd:cheque_details
cheque_details_detail_invdate
cheque_details_detail_duedate
cheque_details_detail_invnumber
cheque_details_detail_origvalue
cheque_details_detail_value
cheque_details_detail_origbasevalue
cheque_details_detail_basevalue
cheque_details_detail_trscode_@name
cheque_details_detail_trsnumber
millions
hundreds_of_thousands
tens_of_thousands
thousands
hundreds
tens
units
cents

Helaas gaan deze Word samenvoeg velden verloren bij het opslaan van .doc bestanden in LibreOffice. Na veel uitzoekwerk bleek dit te komen doordat de samenvoeg velden niet gekoppeld zijn aan een database.

Binnen LibreOffice kan er net als in Microsoft Word gewerkt worden met samenvoeg velden. In het LibreOffice worden deze samenvoeg velden ook wel “Mail merge fields” genoemd.

LibreOffice - Mail merge fields

Deze “Mail merge fields” kunnen echter niet vrij ingevoerd worden. In plaats daarvan moeten er kolommen uit een database tabel geselecteerd worden. Door een CSV bestand aan te maken met alle beschikbare Twinfield samenvoeg velden is dit echter eenvoudig te realiseren.

HeaderStart,HeaderEnd,FooterStart,FooterEnd,addressinv_name,addressinv_addr1,addressinv_addr2,addressinv_addr3,addressinv_postcode,addressinv_city,addressinv_country_@code,addressinv_country,addressinv_addr4,addressinv_addr5,addressdel_name,addressdel_addr1,addressdel_addr2,addressdel_addr3,addressdel_postcode,addressdel_city,addressdel_country_@code,addressdel_country,addressdel_addr4,addressdel_addr5,header_invdate,header_duedate,header_perfdate,header_invnum,header_vatnumber,header_customer,header_customername,header_period,header_headerdescr,header_footerdescr,header_printstatus,header_paycode,bank_name,bank_account,header_print,header_printcount,header_usrcode_@name,header_authoriser_@name,TableStart:lines,TableEnd:lines,lines_line_@id,header_currency,lines_line_artcode,lines_line_subcode,lines_line_name,lines_line_sname,lines_line_extref1,lines_line_extref2,lines_line_extref3,lines_line_dim2,lines_line_dim2_@name,lines_line_dim3,lines_line_dim3_@name,lines_line_dim4,lines_line_dim4_@name,lines_line_fincode,lines_line_finnumber,lines_line_acpay_@name,lines_line_perfdate,lines_line_qty,lines_line_descr,lines_line_unitsprice_@regional,lines_line_unitspriceinc_@regional,lines_line_currency,lines_line_taxrate,lines_line_taxvalue_@regional,lines_line_invvalue_@regional,lines_line_invvalueinc_@regional,TableStart:taxlines,TableEnd:taxlines,calclines_taxline_currency,calclines_taxline_taxname,calclines_taxline_perftype,calclines_taxline_perfyearmonth,calclines_taxline_taxover_@regional,calclines_taxline_taxvalue_@regional,calclines_taxline_valueincl_@regional,calclines_totalline_valueexcl_@regional,calclines_totalline_taxvalue_@regional,calclines_totalline_value_@regional,lines_line_teq_week,lines_line_teq_month,lines_line_teq_quarter,lines_line_dim1,lines_line_dim1_@name,lines_line_dim1_@sname,lines_line_dim1_@prjinvdescr,lines_line_dim2_@sname,lines_line_dim2_@prjinvdescr,lines_line_transdate,TableStart:timelines,TableEnd:timelines,time_line_user_@name,time_line_user_@sname,time_line_user,time_line_transdate,time_line_project_@name,time_line_project_@sname,time_line_project_@prjinvdescr,time_line_project,time_line_activity_@name,time_line_activity_@sname,time_line_activity_@actinvdescr,time_line_activity,time_line_descr,time_line_qty,time_line_price,calclines_totalline_value_@predecimal,calclines_totalline_value_@postdecimal,header_customer_@account,customer_custname,customer_name,customer_addr1,customer_addr2,customer_addr3,customer_postcode,customer_city,customer_country,customer_country_@name,customer_modified,customer_dimcode,customer_basecurrency,customer_basecurrency_@name,customer_basecurrency_@shortname,customer_reportingcurrency,customer_reportingcurrency_@name,customer_reportingcurrency_@shortname,customer_invoicecurrency,customer_invoicecurrency_@name,customer_invoicecurrency_@shortname,customer_totalbasevalueopen,customer_totalrepvalueopen,customer_totalvalueopen,TableStart:customer,TableEnd:customer,customer_detail_invnumber,customer_detail_inpdate,customer_detail_basevalueopen,customer_detail_valueopen,customer_detail_repvalueopen,customer_detail_basevalue,customer_detail_value,customer_detail_repvalue,customer_detail_basevaluepaid,customer_detail_valuepaid,customer_detail_repvaluepaid,customer_detail_days,customer_detail_duedate,customer_detail_currency,customer_detail_currency_@name,customer_detail_currency_@shortname,customer_detail_description,customer_totalbasevalueopen_@predecimal,customer_totalrepvalueopen_@predecimal,customer_totalvalueopen_@predecimal,customer_totalbasevalueopen_@postdecimal,customer_totalrepvalueopen_@postdecimal,customer_totalvalueopen_@postdecimal,customer_account,name,addr1,addr2,addr3,addr4,addr5,postcode,city,country,dimcode,dimname,date,office_code,office_name,office_vatnumber,office_address_line1,office_address_line2,office_address_line3,office_address_line4,office_address_line5,office_address_line6,office_address_zipcode,office_address_city,office_address_country,office_address_telephone,office_address_fax,bank_code,bank_ascription,bank_iban,bank_accountnumber,bank_nationalbic,bank_bic,bank_address_line1,bank_address_line2,bank_address_line3,bank_address_line4,bank_address_line5,bank_address_line6,bank_address_zipcode,bank_address_city,bank_address_country,bank_address_telephone,bank_address_fax,TableStart:details,TableEnd:details,details_detail_invdate,details_detail_duedate,details_detail_invnumber,details_detail_origvalue,details_detail_value,details_detail_origbasevalue,details_detail_basevalue,details_detail_trscode_@name,details_detail_trsnumber,origvalue,value,currency,valuetext,TableStart:cheque_details,TableEnd:cheque_details,cheque_details_detail_invdate,cheque_details_detail_duedate,cheque_details_detail_invnumber,cheque_details_detail_origvalue,cheque_details_detail_value,cheque_details_detail_origbasevalue,cheque_details_detail_basevalue,cheque_details_detail_trscode_@name,cheque_details_detail_trsnumber,millions,hundreds_of_thousands,tens_of_thousands,thousands,hundreds,tens,units,cents

Dit bestand kan opslagen worden in Twinfield.csv en vervolgens gebruikt worden bij het invoegen van een “Mail merge field”. Vervolgens kun je je sjabloon helemaal naar wens inrichten en opslaan in het ODF Text Document (.odt) formaat.

Zodra het sjabloon geüpload moet worden naar Twinfield is een bestandsnaam met de extensie .doc, .dot, .docx of .dotx nodig. Bij het uploaden van andere bestanden zal Twinfield de volgende foutmelding weergeven:

Selecteer een DOC-, DOT-, DOCX- of DOTX-bestand.

Als we ons ODF Text Document echter opslaan volgens het “” of “” formaat geeft Twinfield de volgende foutmelding:

De Word-sjabloon bevat geen samenvoegvelden.

Daarom slaan we ons bestand niet op volgens dit formaat maar wijzigen we ons “bestandsnaam.odt” simpelweg naar “bestandsnaam.odt.dot”. Vreemd genoeg kan Twinfield het ODF Text Document met een geldige extensie gewoon correct verwerken.

Helaas werken niet alle aspecten van een ODF Text Document even goed in Word en dus Twinfield. Zo wordt de opmaak van afbeeldingen en frames niet altijd goed over genomen. Dit probleem is echter vrij eenvoudig te omzeilen door puur met een tabellen opmaak te werken.