I've been trying to make links work in openTBS generated documents. No luck so far :(
I'm totally lost, spent a few days trying to figure out how to do that. It's bugging me big time because this seems to be a thing openTBS would handle on its own, without a problem.
I this is my php code:
<?
include_once('tbs/tbs_class.php');
include_once('tbs/plugins/tbs_plugin_opentbs_1.8.1/tbs_plugin_opentbs.php');
$TBS = new clsTinyButStrong('!-,-!');
//the special pattern is needed because
//word replaces [] brackets when put in link's href.
$TBS -> Plugin(TBS_INSTALL, OPENTBS_PLUGIN);
//some variables for mergeing with the template
$tmpl_headname='Sarah';
$tmpl_headlink='http://example.com/?user=sarah';
$tmpl_items = array(
array('title'=>'My title', 'url'=>'http://myurl.com/firstarticle'),
array('title'=>'My second title', 'url'=>'http://myurl.com/secondarticle'),
array('title'=>'My third title', 'url'=>'http://myurl.com/thirdarticle')
);
$TBS->LoadTemplate('sampledoc.docx');
$TBS->MergeBlock('item',$tmpl_items);
$TBS->Show(OPENTBS_DOWNLOAD, 'sample_filename_doc');
?>
My Word template:
This is your unique link, !-onload.tmpl_headname-! (points to: !- onload.tmpl_headlink-!)
!-item;block=begin;tbs:page-!
!-item.title-!
Link to the website (points to: !-item.url-!)
***
!-item;block=end;tbs:page-!
In my Word template, the links point to !-item.url-!
, and it stays the same after running openTBS on it. The problem is, that in the Docx zip archive, in word/_rels/document.xml.rels˙
, they appear unchanged:
<Relationship TargetMode="External" Target="!-item.url-!" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rId8"/>
Any help is greatly appreciated! :)
Also, for those, who want to change link urls with openTBS (but not in mergeblock mode!), I found a workaround: Open the document.xml.rels as a template, and run a openTBS on it:
$TBS->LoadTemplate('tbs/sampledoc.docx#word/_rels/document.xml.rels');
This hack doesnt work with mergeblock, because !-item.url-! gets to be every resource's Target, and you can't tell which one for which block iteration :(
Edit:
OpenTBS generates ids with rId
prefix: rId1
,rId2
, etc. Every other item in the resources file is linked with rId[x]
pattern.
After running openTBS, I get this xml code in document.xml,
representing the following Word section:
***
My second title
Link to the website
With a link on the "link to the website" bit. ...
<w:p w:rsidRDefault="00886D12" w:rsidP="00886D12">
<w:r>
<w:t xml:space="preserve">
***
</w:t>
</w:r>
<w:r>
<w:br/>
</w:r>
<w:r>
<w:t>
My second title
</w:t>
</w:r>
<w:r>
<w:br/>
</w:r>
<w:hyperlink r:id="rId7" w:history="1">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t xml:space="preserve">
Link to the website
</w:t>
</w:r>
</w:hyperlink>
</w:p>
...
The document.xml.rels file looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="!-item.url-!" TargetMode="External"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item1.xml"/>
<Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/>
<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>
<Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
</Relationships>
I might be able to duplicate the hyperlink resource item with a special openTBS code put inside the Target attribute, but then I would have to use the new rIDs on the document.xml too.
Thanks for your help!
Yepp, got it right! So, based on Sarah's suggestions, I was able to fake linking rId's in the Word document's rels file and document.xml.
This is how I did:
In the word file, every link in the block points to a sample url http://mypage.com
Doesn't matter which url you choose, and here's why: After the block is multiplied several times, all the links in these blocks will stay linked to the same <Realtionship>
tag in the rels file, and we are about to modify this connection, so no link will point to the original mypage.com
<Relationship>
item.
For this to happen, I inserted the following text after the actual text inside the link:
!-item.rId;att=w:hyperlink#r:id;-!
So my link now looks like :My website!-item.rId;att=w:hyperlink#r:id;-!
. What this tag does is that it changes the default r:id attribute of the link (which is the attribute Word links items by between the document.xml
and the rels file _rels/document.xml.rels
). The r:id will be changed to a custom id name, which you have to supply in the php array you merge by! Here's my php code for the rId's:
$tmpl_items = array(
array('title'=>'My title', 'url'=>'http://myurl.com/firstarticle','rId' => 'linkRid1'),
array('title'=>'My second title', 'url'=>'http://myurl.com/secondarticle','rId' => 'linkRid2'),
array('title'=>'My third title', 'url'=>'http://myurl.com/thirdarticle','rId' => 'linkRid3')
);
notice, that rId is the value we will replace default r:ids with. Of course the openTBS tag gets removed from the link text.
!-item.block;block=begin;-!
<Relationship Id="!-item.rId-!" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="!-item.url-!" TargetMode="External"/>
!-item.block;block=end;-!
Run merge_block on the rels file too. This way, <Relationship>
items will be generated by openTBS too. Also, this means, that by now, your Word file is corrupted, because you broke the valid XML syntax in the rels file, and cannot edit in in Word any more.
$TBS->LoadTemplate('tbs/sampledoc_stackof2.docx'); $TBS->MergeBlock('item',$tmpl_items); $TBS->LoadTemplate('#word/_rels/document.xml.rels'); $TBS->MergeBlock('item',$tmpl_items);
After all this hassle, everything looks a-okay. I have these in the rels file:
<Relationship Id="linkRid1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://myurl.com/firstarticle" TargetMode="External"/>
<Relationship Id="linkRid2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://myurl.com/secondarticle" TargetMode="External"/>
<Relationship Id="linkRid3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://myurl.com/thirdarticle" TargetMode="External"/>
and I got the rId's in the document.xml too:
<w:p w:rsidRDefault="004842D8" w:rsidP="008A11F0">
<w:hyperlink r:id="linkRid1" w:history="1">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t>
My website
</w:t>
</w:r>
</w:hyperlink>
</w:p>
Running openTBS now on the document will gerenate the docx file, with the merged links. The only downside is, that with the rels file hacked, I lost xml validity, and the chance to edit the document in Word later. Any suggestion, how to avoid that would be appriciated, although we'd need a solution where Word would keep the hacked parts of the rels file intact after saving the template doc.
Thanks Sarah for the great amount of help!
I'm opening a bottle of wine now.