I have a PHP function that generates vCard data from the WordPress ACF plugin. The German text is not displaying correctly in Outlook’s desktop version, but it works fine on the mobile version. Here’s the code I’m using to generate the vCard:
function generate_vcard($post_id) {
// Get ACF field values for the post
$title = utf8_encode(get_field('title', $post_id));
$first_name = utf8_encode(get_field('first_name', $post_id));
$last_name = utf8_encode(get_field('last_name', $post_id));
$position = utf8_encode(get_field('position', $post_id));
$company = utf8_encode(get_field('company', $post_id));
$birthday = utf8_encode(get_field('birthday', $post_id));
$office_phone = utf8_encode(get_field('office_phone', $post_id));
$cell_phone = utf8_encode(get_field('cell_phone', $post_id));
$email_1 = utf8_encode(get_field('email_1', $post_id));
$email_2 = utf8_encode(get_field('email_2', $post_id));
$website = utf8_encode(get_field('website', $post_id));
// Get profile image URL from ACF field
$profile_image = get_field('profile_image', $post_id);
// Encode the image to base64
$image_data = file_get_contents($profile_image);
$base64_image = base64_encode($image_data);
// Generate vCard content
$vcard = "BEGIN:VCARDrn";
$vcard .= "VERSION:3.0rn";
$vcard .= "PHOTO;TYPE=JPEG;ENCODING=b;VALUE=URL:$base64_imagern";
$vcard .= "FN:$first_name $last_namern";
$vcard .= "N:$last_name;$first_name;;;rn";
$vcard .= "ORG;CHARSET=windows-1252:$companyrn";
$vcard .= "TITLE:$positionrn";
$vcard .= "BDAY:$birthdayrn";
$vcard .= "TEL;TYPE=WORK,VOICE:$office_phonern";
$vcard .= "TEL;TYPE=CELL,VOICE:$cell_phonern";
$vcard .= "EMAIL:$email_1rn";
$vcard .= "EMAIL:$email_2rn";
$vcard .= "URL:$websitern";
$vcard .= "END:VCARDrn";
// Set headers to trigger download with Windows-1252 encoding
header("Content-Type: text/vcard; charset=windows-1252");
header("Content-Disposition: attachment; filename=contact.vcf; charset=windows-1252");
// Output vCard content with Windows-1252 encoding
echo $vcard;
exit;
}
add_action('wp', 'export_vcard');
function export_vcard() {
if (isset($_GET['export_vcard']) && $_GET['export_vcard'] == 1) {
$post_id = get_the_ID();
generate_vcard($post_id);
}
}
I meant that the German text in the vCard is not rendering as expected in Outlook’s desktop version. the German text appears für
but the actual text is für
.
I have tried changing the encoding of the vCard file to UTF-8, but that did not fix the problem.
Does anyone know why this is happening and how to fix it?
2
Answers
Here are the changes I made:
Consistent Encoding: I replaced
utf8_encode
withmb_convert_encoding
in theget_utf8_field
function. This function is more flexible and can handle different types of encodings. I also set the charset in the headers toUTF-8
.UTF-8 BOM: I added the UTF-8 Byte Order Mark (BOM) at the beginning of your vCard content.
Quoted-printable Encoding: I didn’t apply this fix because it’s not necessary when using UTF-8 encoding. If you still encounter issues, you might want to consider applying this fix.
WordPress is using
utf8mb4
by default, so you must not useutf8_encode
onget_field
as this will result in double-encoding. Stay with utf-8 (it’s the recommended default for vCard 3.0 and a must for vCard 4.0) when creating the vCard and setting the headers. Do not add a BOM. Useutf-8
in all lower case, as some versions of Outlook do not accept in all upper case.Create a minimum reproducible example an then go from there. I’ve tested with:
and this imports just fine. If you still encounter problems thereafter, export a vCard from the client in question (e.g. Outlook) and open both the export and your vCard in a text editor to compare them.