문제

I've been trying to make links work in openTBS generated documents. No luck so far :(

  • What I can do: With a bit of a hack, I can create a template with a link, and change the link caption and the href by my variables.
  • What I can not do: Create a block, with a link in it, fill it up with MergeBlock and make it work with my php array of objects.

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!

도움이 되었습니까?

해결책 2

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:

  1. 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.

  2. 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.

  3. Hack the rels file. !-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;-!
  4. 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.

다른 팁

This is too hard to show in a comment.

You may need to use the att parameter: http://www.tinybutstrong.com/manual.php#html_field_prm

Something like (untested):

<Relationship TargetMode="External" Target="" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rId8">
    !-block=item;att=Target;item.url-!
</Relationship>

You could toy with the att=Relationship#Target rather than opening the Relationship tag out like I did too. Something like this (really untested):

<Relationship TargetMode="External" Target="" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rId8"/>
!-block=item;att=Relationship#Target;item.url-!

Does this allow the block to repeat properly so you don't get your block all grouped into a single Target attribute?

You will also need to come up with a unique id for each rId attribute, obviously. You may want to follow OpenTBS' example here and use a different structure than Word does to avoid conflicts. Something like rId=mytbs1 rather than just rId=1 (OpenTBS uses opentbs1 for pictures but you don't want to conflict there either).

I'm sure Skrol29 will be reading this post and will consider whether it is possible/reasonable to update OpenTBS to handle this.


Edit:

After seeing the XML output my best guess would be to add a unique rId that you want to use to your array that populates your block. Something like:

$items = array(
    array('title' => 'My Title1', 'url' => 'http://my.url', 'rId' => 'myTBS1'),
    array('title' => 'My Title2', 'url' => 'http://my.url', 'rId' => 'myTBS2'),
);

Then, in your template:

!-item;block=begin;tbs:page-!
    !-item.title-!
    Link to the website
    ***
!-item;block=end;tbs:page-!

Where 'Link to the website' has a hyperlink whose content is (something like):

!-block=item;item.url-!!-item.rId;att=rId-!

Then in your rels template:

<Relationship TargetMode="External" Target="" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rId8">
    !-block=item;att=Target;item.url-!
    !-item.rId;att=rId-!
</Relationship>

Just an idea to keep the rIds linked. I'm not sure I got the syntax just right, and what the rules are on multiple attribute changes on a single tag... Hopefully Skrol29 will come along with a better solution if we are barking up the wrong tree here.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top