Room 208

Elaborate Burn

Changing the type of an existing Tumblr post

Update: The method detailed in this article does not work on the new dashboard rolled out in late January 2015. See this post for further details and an alternative strategy. The original post follows.


Tumblr doesn’t provide any way to change the type of a post in its user interface – from a link to a regular text entry, say. This might lead you to assume that your only solution is to delete the original and make a new post, breaking links and losing notes in the process. As you might have guessed from the fact that I’m making this post, however, you would be wrong. You just have to be comfortable with twiddling with some hidden form fields.

Don’t worry. It’s not that complicated.

Continue reading

The first step, of course, is to pull up the appropriate post’s edit page. Simple enough.

Now it’s time to break out your browser’s DOM inspector. Right-click somewhere on the edit form, and click “Inspect Element” or what have you. (You might have to turn on developer tools first.)

If you elected to inspect the text entry for the post title, like I did, you’ll find yourself somewhere around here:

<div id="post_content">
  <div class="main_content regular_form">
    <div class="post_type">
      <input type="hidden" value="regular" name="post[type]">
      <div class="file_upload_overlay offscreen"><!-- ... --></div>
      <div class="input_wrapper">
        <input class="borderless full title" id="post_one"name="post[one]" type="text" value=""autocomplete="off" placeholder="Title">
        <label class="optional" for="post_one">Optional</label>
      </div>
      <div class="textarea_wrapper"><!-- ... --></div>
    </div>
    <section class="tag_editor"><!-- ... --></section>
  </div>
  <nav id="post_controls" class="clearfix"><!-- ... --></nav>
  <ul class="messages errors"></ul>
</div>

Hm, what’s that say up there? post[type]?

<div id="post_content">
  <div class="main_content regular_form">
    <div class="post_type">
      <input type="hidden" value="regular" name="post[type]">
      <div class="file_upload_overlay offscreen"><!-- ... --></div>
      <div class="input_wrapper">
        <input class="borderless full title" id="post_one"
          name="post[one]" type="text" value=""
          autocomplete="off" placeholder="Title">
        <label class="optional" for="post_one">Optional</label>
      </div>
      <div class="textarea_wrapper"><!-- ... --></div>
    </div>
    <section class="tag_editor"><!-- ... --></section>
  </div>
  <nav id="post_controls" class="clearfix"><!-- ... --></nav>
  <ul class="messages errors"></ul>
</div>

Bingo. We just have to change the value of this hidden field, submit the form with the button as usual, and we’ll have successfully changed the post type. You can use one of regular (for text posts), note (for answers to asks – but note that the question is stored elsewhere and can’t be changed), photo, quote, link, chat, audio, or video. I want this to be a quote post instead of a regular one, so:

<input type="hidden" value="quote" name="post[type]">

And let’s save the post…

"Post cannot be
empty."

Huh. Wait, what?

Right, so the other thing I forgot to mention is that the order of fields in a Tumblr post differs from type to type. You might think that the main content would be in a field named content, the title in one named title, and so forth, but that’s apparently too logical for Tumblr. What actually happens is that there are three fields called, generically enough, post[one], post[two], and post[three], which take on different meanings depending on the post type:

Type post[one] post[two] post[three]
Text Title Content
Answer Answer
Photo Caption
Quote Quote Source
Link Title URL Caption
Chat Title Content
Audio Caption
Video Embed URL Caption

So since I’m converting a title-less text post to a quote post, Tumblr thinks I’m actually trying to submit an empty quote with the original body text as the source, and that obviously won’t do. Fortunately, there are two easy ways around this problem. The first is to change the names of the form fields in the inspector:

<div id="post_content">
  <div class="main_content regular_form">
    <div class="post_type">
      <input type="hidden" value="regular" name="post[type]">
      <div class="file_upload_overlay offscreen"><!-- ... --></div>
      <div class="input_wrapper"><!-- ... --></div>
      <div class="textarea_wrapper">
        <div id="post_two_manual_toolbar" class="manual_toolbar">
          <!-- ... -->
        </div>
        <div class="resize_textarea_container">
          <textarea class="full borderless resize_y" id="post_two"
            name="post[one]" style="height: 234px; min-height: 85px;"
            autofocus=""><!-- ... --></textarea>
          <span onclick="return false;" tabindex="-1"
            class="resize_textarea_anchor"></span>
        </div>
        <div class="resize_textarea_clearfix"></div>
        <div class="textarea_shim"><!-- ... --></div>
      </div>
    </div>
    <section class="tag_editor"><!-- ... --></section>
  </div>
  <nav id="post_controls" class="clearfix"><!-- ... --></nav>
  <ul class="messages errors"></ul>
</div>

I didn’t change the id here, but remember that what actually matters when submitting the form is the name, not the id. Note that you may also have to change the names of fields you haven’t used to keep them from clashing with your renamed ones.

The other option, of course, is to just copy-paste everything where it needs to go. This one works best if you don’t have any linebreaks in the content you’re moving.

Either way, we can now submit the form and be on our merry way.