Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Overriding tw-story's parent? (Harlowe)

I'm trying to integrate Twine output into a large CMS. A problem I can't seem to work around is how Harlowe renders the tw-story passage *after* the close of the document's body tag. So even if I include it in the proper location, it seems some JS moves the content after the body tag, which means that other PHP elements render above it. I've browsed through the source on bitbucket and can't see where this location is set or how to override it.

TLDR: I need my twine stuff in the body tag, not after it. Any ideas?

Apologies if this has been asked before, it was impossible find relevant info when doing a search for the keywords "body" and "tw-story".

Comments

  • A standard method used to embed the contents of one HTML file within another HTML file is to use an iframe element in the parent HTML file to reference the child HTML file.

    Each Story Format is a mini web-application, so the Javascript engine code and CSS used within it make assumptions about the HTML structure of the document they are embedded within. I am not sure what the outcome of moving the engine code into a document with a different structure will be because I have never tried doing that.

    The "location" of the tw-story element is hard-wired in the template.html file
  • I ran into this a while back when using Harlowe to embed a story into an existing HTML layout. There is a solution that may work for you, but it's a little kludgy. Also, all of this information dates from when I created that story last year, so hopefully this all still checks out but someone please correct me if any of this is out of date. ;)

    Now, as greyelf mentioned, Harlowe makes assumptions about the story structure, so I don't know if moving the tw-story element around will break anything. My story where I used this method also used a fair number of Harlowe features and they all worked fine, but I would definitely do some thorough testing before depending on this method for other stories.

    If my memory hasn't failed me, the issue is that whenever Harlowe switches passages, it removes the <tw-story> element, then renders the new passage in a new <tw-story> element and appends that to the html element, so even if you move it, as soon as you navigate to a new passage, it's back down there.

    The method I used to modify this behavior has two components. First, I added these CSS rules:
    	tw-story {
    		display: none !important;
    	}
    	#content > tw-story {
    		display: block !important;
    	}
    

    The first rule forces all tw-story elements, and therefore passages, to be hidden, and the second rule overrides the first rule and forces passages to be visible when in the intended location (which in my case was a <div id="content">). If I remember correctly, I had to flag them as !important rules to override the existing rules from the story format; I warned you this was kludgy.

    The second component is this single statement (using jQuery, which Harlowe includes):
    	$('html>tw-story').appendTo($('#content'));
    

    That finds any tw-story element that's a child of the html element, and relocates it to the proper parent element. The trick is the behavior where that tw-story element gets removed and recreated every time you view a new passage, so you need to run that statement again every time a new passage is rendered.

    In my case, I already had a real time element to the surrounding page, so I just added that code there to make sure it was called repeatedly, but if you don't already have that, you'll need to make sure that code gets called either immediately when a new passage is rendered, or as soon as possible afterwards to avoid any significant lag for the user. The easiest solution would probably be to use setInterval() to run that code fairly often, maybe a few times per second, so as soon as a new passage gets rendered, it gets moved. If a new passage hasn't been rendered, there shouldn't be any side effects of that code since it won't find anything to move, so it should be safe to call any time.

    For what it's worth, when I originally cooked this up, I started looking into how Harlowe handles its passage rendering, and it looked like in the 2.0 version of Harlowe it checks the parent element of the existing passage, then appends the newly-rendered passage to that same element, which would make this fairly simple to do, but we're still on 1.x so this was the only solution I found at the time.

    Hopefully some version of that will work for you, but good luck. ;)
  • gnustoboz wrote: »
    I ran into this a while back when using Harlowe to embed a story into an existing HTML layout. There is a solution that may work for you, but it's a little kludgy. Also, all of this information dates from when I created that story last year, so hopefully this all still checks out but someone please correct me if any of this is out of date. ;)
    ...
    This worked perfectly! Well, sort of. What I ended up doing was using jQuery to move my PHP output after the Twine embed instead of the other way around. It's a little slow but I'm hoping to hide that with something like LazyLoad.js.

    Thanks!!
Sign In or Register to comment.