5

I'm using custom (commercial) fonts in my project. Everything works well in the frontend.

I noticed however that, when trying to add this font to the TinyMCE iframe, I get a 403 for the webfonts. The problem seems to be, that requests from the iframe do not have a referrer. And fonts.com needs a referrer to validate the request.

Any thoughts?

1
  • We need so much more detail to answer this one. And then there's the problem that most of us won't be able to replicate this issue without a font bought from fonts.com. Any idea how we could bring this on topic? Rework your question?
    – kaiser
    Mar 5, 2013 at 11:32

3 Answers 3

5

I ran into this issue with Typekit, here's my solution:

http://www.tomjn.com/150/typekit-wp-editor-styles/

add_filter("mce_external_plugins", "tomjn_mce_external_plugins");
function tomjn_mce_external_plugins($plugin_array){
    $plugin_array['typekit']  =  get_template_directory_uri().'/typekit.tinymce.js';
    return $plugin_array;
}

and this js:

(function() {
    tinymce.create('tinymce.plugins.typekit', {
        init: function(ed, url) {
            ed.onPreInit.add(function(ed) {

                // Get the DOM document object for the IFRAME
                var doc = ed.getDoc();

                // Create the script we will add to the header asynchronously
                var jscript = "(function() {\n\
                    var config = {\n\
                        kitId: 'xxxxxxx'\n\
                    };\n\
                    var d = false;\n\
                    var tk = document.createElement('script');\n\
                    tk.src = '//use.typekit.net/' + config.kitId + '.js';\n\
                    tk.type = 'text/javascript';\n\
                    tk.async = 'true';\n\
                    tk.onload = tk.onreadystatechange = function() {\n\
                        var rs = this.readyState;\n\
                        if (d || rs && rs != 'complete' && rs != 'loaded') return;\n\
                        d = true;\n\
                        try { Typekit.load(config); } catch (e) {}\n\
                    };\n\
                    var s = document.getElementsByTagName('script')[0];\n\
                    s.parentNode.insertBefore(tk, s);\n\
                })();";

                // Create a script element and insert the TypeKit code into it
                var script = doc.createElement("script");
                script.type = "text/javascript";
                script.appendChild(doc.createTextNode(jscript));

                // Add the script to the header
                doc.getElementsByTagName('head')[0].appendChild(script);

            });

        },
        getInfo: function() {
            return {
                longname: 'TypeKit For TinyMCE',
                author: 'Tom J Nowell',
                authorurl: 'http://tomjn.com/',
                infourl: 'http://twitter.com/tarendai',
                version: "1.1"
            };
        }
    });
    tinymce.PluginManager.add('typekit', tinymce.plugins.typekit);
})();

It inserts the typekit code inside the iframe, you'll want to change the code to the fonts.com embed script and test. Unfortunately, I'm unfamiliar with the security safeguards at fonts.com and the exact embed codes they used

6
  • Thanks for the answer. But I'm afraid it willl not work because of the referrer issue, like you said in your blogpost ("Update").
    – Aron Woost
    Mar 5, 2013 at 12:09
  • I'm aware of that, but in the vast majority of cases it does work and still works
    – Tom J Nowell
    Mar 5, 2013 at 12:12
  • The question then is: why? :) Since referrer check is part of their business model.
    – Aron Woost
    Mar 5, 2013 at 20:06
  • If it works for typekit it may work for fonts.com, the best way of knowing is to try
    – Tom J Nowell
    Mar 5, 2013 at 21:51
  • also chances are it didn't work those few times because of browser cache being funny inside the iframe, it's working for me 99% of the time even today
    – Tom J Nowell
    Mar 6, 2013 at 9:51
1

If you want add your custom styles to TinyMCE editor in WordPress, you need to create a css file, for instance editor.css and put it into your theme folder. After it, add your font face initialization in this css, like this:

@font-face {
  font-family: 'Your font name';
  font-style: normal;
  font-weight: 400;
  src: local('Your font name'), local('Your font name'), url(http://yoursite.com/path/to/your/font.woff) format('woff');
}

body {
    font-family: 'Your font name', Helvetica, Arial, sans-serif;
}

/* etc styling */

Then you need to properly enqueue your editor.css file. To do it you need to call add_editor_style style function:

add_action( 'after_setup_theme', 'wpse8170_init_editor_styles' );
function wpse8170_init_editor_styles() {
    add_editor_style( 'editor.css' );
}

If you have .ttf font file only, you need to convert it to .woff. You can do it here.

3
  • 1
    it's not about how to normally get web-/custom-font to display inside TinyMCE but rather how to make commercial fonts work iside TinyMCE's iFrame. Mar 5, 2013 at 11:47
  • @pkyeck I have added a link, where everybody can convert .ttf to .woff. Mar 5, 2013 at 11:53
  • it's a commercial webfont and is hosted on the fonts.com server Mar 5, 2013 at 12:54
1

Use this function in your plugin or theme's functions.php file:

// Tell the TinyMCE editor to use a custom stylesheet
add_filter('the_editor_content', "firmasite_tinymce_style");
function firmasite_tinymce_style($content) {
    add_editor_style('assets/css/customfont.php');

    // This is for front-end tinymce customization
    if ( ! is_admin() ) {
        global $editor_styles;

        $editor_styles = (array) $editor_styles;
        $stylesheet    = array();

        $stylesheet[] = 'assets/css/customfont.php';        

        $editor_styles = array_merge( $editor_styles, $stylesheet );

    }
    return $content;
}

So we called a customfont.php file to wp editor. This file is a php file but will work as a css file. And this is our customfont.php:

<?php
/*
 * This file using for loading custom google font in wp-editor
*/
define('WP_USE_THEMES', false);
if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/wp-blog-header.php')) {
    /** Loads the WordPress Environment and Template */
    require($_SERVER['DOCUMENT_ROOT'] . '/wp-blog-header.php');
    status_header(200);
    header("Content-type: text/css");
} else {
    exit;
}
?>
@import url(http://fonts.googleapis.com/css?family=<?php echo urlencode("Amarante"); ?>&subset=latin,latin-ext);
body { font-family: Amarante,sans-serif !important;}

This is an example from Firmasite theme. Maybe this will work for you. If you still getting 403, you can add some php header like header("Referer: http://example.org");

5
  • why did you need to use this "proxy" - couldn't you just include a normal css add_editor_style()? why so complicated? Mar 5, 2013 at 12:53
  • can you change header("Referer: http://example.org"); in css file? Mar 5, 2013 at 12:55
  • no, but it doesn't matter because even setting the referer inside the "css" won't get the fonts to load :( Mar 6, 2013 at 8:13
  • this doesn't fix the issue, it makes use of bad practices ( including the blog header php from a separate entry point ), and makes use of an undefined var ( firmasite_settings )
    – Tom J Nowell
    Mar 6, 2013 at 9:53
  • its just example.. seems i forgot to clear 1 undefined var which i clear other all. This is not a bad example. Its a good example of how to create a php file that acts like css in wordpress. I dont know what type of security check font.com have so its of course possible it wont work for them. Mar 6, 2013 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.