3

I'm writing a tutorial on using the R language to do some applied statistics. An example post is:

http://mcmcinirt.stat.cmu.edu/archives/223

I would like to have all of the blocks of source code be loaded from local files on the webserver. In that way, I could use git to sync them with the files that I'm actually using to develop the examples.

As it stands, I write the code on my machine, generate the graphs / check that it works, and then copy the final code into the text of the blog. This leads to duplication headaches.

Is it possible to avoid this kind of code duplication? (Either in the way I suggest or perhaps a more WordPress friendly way?)

2 Answers 2

1

I would not use the media uploader for this because you want to "use git to sync them with the files that I'm actually using". There is no straightforward way to sync files uploaded via the uploader, or to update/replace those files. Core functionality in that respect is quite limited. You'd be FTPing into the server to update the files anyway and if your site stores in year/month folders just finding the files would be troublesome.

I would skip that hassle, create a directory for the R files files, and load them with a shortcode:

function srcfile_shortcode($atts='',$content='') {
  $uploads = wp_upload_dir();
  $file = $uploads['basedir'].'/rfiles/'.$atts['file'].'.r';
  if (is_readable($file)) {
    $file = file_get_contents($file);
    return '<pre>'.$file.'</pre>';
  } else {
    return 'Can not read file: '.$file;
  }
}
add_shortcode('srcfile','srcfile_shortcode');

That should load files from wp-content/uploads/rfiles with a name that matches the file shortcode attribute-- that is [srcfile file="abc" /] would load wp-content/uploads/rfiles/abc.r.

You can keep the directory up to date however you like-- FTP, or Git.

3
  • Adding this to the functions.php file in my child theme worked perfectly. Thank you so much! (Also, I edited the code above to spit out a simple error if the file can't be printed. I spent 30 minutes wondering why it wasn't working before I realized that I should make it fail with a message instead of silently.) Commented Oct 14, 2013 at 22:55
  • I approved the edit but I'd probably make it send an email or log a message rather than print one to the screen. Your call on that though.
    – s_ha_dum
    Commented Oct 14, 2013 at 22:58
  • That is a very good point. I'll have to change that on my end once the site goes into production. Commented Oct 14, 2013 at 23:09
2

Use the built-in tool: the media library. There are two steps to do that:

  1. Allow uploading txt files, to enable the upload.
  2. Filter the AJAX action that inserts the HTML code.

1. Allow txt file upload

This is pretty simple: filter upload_mimes and add your types to the existing list.

add_filter( 'upload_mimes', 'extend_upload_mimes_for_txt' );

function extend_upload_mimes_for_txt( $mime_types = array() )
{
    $mime_types['txt']  = 'text/plain';
    $mime_types['r']    = 'text/plain';
    return $mime_types;
}

2. Change the output for r files

Let’s say you upload your r files with the extension .r. Filter media_send_to_editor, check the extension, include the complete content and create the proper markup.

add_filter( 'media_send_to_editor', 'embed_r_txt_files', 10, 3 );

function embed_r_txt_files( $html, $id, $attachment )
{
    if ( 'r' !== pathinfo( $attachment['url'], PATHINFO_EXTENSION ) )
        return $html;

    $content = file_get_contents( get_attached_file( $attachment['id'] ) );

    return '<pre class="language-r"><code>' 
        . esc_html( $content ) 
        . '</code></pre>';
}

I guess you have tweak the details, but this should be a start.

1
  • +1 interesting idea. In case you understand that the media file uploader now gets used as file > content converter. Got around that fact after reading it the third time.
    – kaiser
    Commented Oct 13, 2013 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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