How product docs are produced at Zendesk

Return to top
Have more questions? Submit a request

24 Comments

  • Ann Jensen

    Hi Charles,

    Thanks for all that information. I have successfully completed the following:

    - Published my DITA topics to HTMLS in Oxygen Author

    - Batch created Zendesk Guide articles from these using the files you shared on GitHub (Batch-publish transformed DITA files to Help Center)

    - Batch updated the same files

    However, I am still at a loss as to best approach for managing images. My DITA source is managed in SVN and the image paths are relative to this. I see you suggest using tools like Amazon S3 and Cyberduck for managing Zendesk Guide images but am unsure of the process. Are these images protected behind authentication or are they public?

    At this point I can't even successfully call the Create Attachment API as I get a 500 response code for no apparent reason.

    Can you advise?

    Thanks in advance,

    Ann

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Ann,

    We don't use any image attachments in our articles.

    We upload the images separately to a folder on Amazon S3 using the Cyberduck FTP client. Amazon s3 is a web server so all the images in our S3 folder automatically get published to the web.

    All the files on S3 get their own URLs. Our URLs all share the same path:

    • https://zen-marketing-documentation.s3.amazonaws.com/docs/en/image1.png
    • https://zen-marketing-documentation.s3.amazonaws.com/docs/en/image2.png
    • ...

    We use these URLs directly in the DITA source files for the articles. Example:

    <image href="https://zen-marketing-documentation.s3.amazonaws.com/docs/en/image1.png"
    id="image_kgv_5xy_np"></image>
    

    Oxygen Author displays the images in the article in the WYSIWYG view.

    From there, it's just a matter of transforming the DITA to HTML and publishing the HTML.

    We recently started automating how we manage images using the S3 API. We use a Python library called Boto 3, which gives you access to the S3 API. For example, uploading an image file with Boto looks like this:

    local_image_path = '/support/images/image1.png'
    
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('zen-marketing-documentation')
    bucket.upload_file(local_image_path, Key='docs/en/image1.png', 
      ExtraArgs={'ACL': 'public-read'})
    

    For more info, see the following resources:

    1
  • Ann Jensen

    Thanks Charles,

    I have registered with Amazon AWS and am using a trial S3 service account. How do you manage authorization to your images in S3?

    Mine are not showing in Oxygen because of lack of authorization (403 error).

    Thanks again,

    Ann

    0
  • Charles Nadeau
    Zendesk Documentation Team

    We use a preference in Cyberduck to automatically set the correct permissions when we upload images:

    1. In Cyberduck, select Cyberduck > Preferences from the menu.
    2. Click the Transfers icon, then the Permissions tab.
    3. In the Uploads section, select Change Permissions, then select To these permissions (for Files).
    4. Set the following permissions:
      1. Owner: Read | Write
      2. Group: Read
      3. Others: Read
    5. Close the dialog box to save the changes.

    You can also change the permissions of the files already on S3:

    1. In Cyberduck, select one or more images, right-click, and select Info > Permissions.
    2. Click the gear icon in the lower left and select Everyone.
    3. Make sure READ is selected in the Permission column of the  "Everyone" row.

    Thanks.

     

    -1
  • Toru Takahashi

    Interesting!

    Zendesk Team doesn't use Guide Editor internally?

     

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Toru,

    Most teams at Zendesk (Advocacy, HR, IT, Facilities, etc) have internal Help Centers and use the Guide editor to write content. As mentioned in the article above, the DITA process the Docs team uses for public-facing docs has a steep learning curve and isn't for everybody. Professional tech writers are generally familiar with it.

    Thanks.

     

    0
  • Toru Takahashi

    Thank you!

    I hope Zendesk Guide focuses on the Doc team's use-case since public documentation can be maintained by the Doc team. Zendesk Guide is too poor to help the internal team yet.

    I like Zendesk. I hope Zendesk Guide would help you and us to write an article and maintain it without any alternative solutions.

    0
  • Moshe Armel

    This is a fascinating and extremely helpful article. Our company's documentation is DITA-based, and are now looking to move from PDF documentation. I would like to know, which DITA repository system to you use? We currently use DITAToo. 

    0
  • William Kellett

    My company is looking at migrating a bunch of DITA-based HTML to a Zendesk Guide. I read this article and was able to use the batch-publish tool successfully for a few topics that I had already created in Guide. However, we'd like to be able to use the tool to create (as opposed to update) articles in bulk from HTML. The readme.md file mentions mods that need to happen to the tool to create articles. Can you elaborate on what mods need to be done?

    Thanks!

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi William,

    You have to use the Create Article endpoint and specify more properties for each article, such as the article's initial author and section, as well as it access permissions. Here's a quick script that'll upload a collection of HTML files to HC:

    https://gist.github.com/chucknado/40ff923e6a2eef6ad529bf32cd12640f

     

     

    1
  • William Kellett

    Hi, Chuck.

    Thanks for passing along the script. Finally getting around to playing with it.

    I'm getting a 404 error when I try to run it. I know it's parsing the files correctly. I believe the API token is good. I know it could be many different things, but if you could point me in a likely direction for this 404 error, I'd be grateful.

    Cheers,

    Will

    0
  • Joey

    Hi William-

    The 404 (Not found) indicates that a resource doesn't exist - it most likely hasn't been created yet, or is being referred to incorrectly. If you have a more explicit example of the error it might be possible to assist, but there are numerous possibilities.

    0
  • Chuck Martin

    I found this article after finding one of the members on your doc team on LinkedIn and asking how this section of your support site was published: https://support.zendesk.com/hc/en-us/categories/200201796-Zendesk-updates

    I want to confirm: Is this the process you use for publishing items in the Announcements, Release notes, and Service notifications sections? If so, I'd like to understand the pre-DITA process better. Specifically, and without revealing anything proprietary, how do you gather, organize, and format these articles. (I see each section seems to have its own content/topic patterns.) And how much of the process is automated? Was that automation easy or did it take a significant amount of developer time? 

    Thanks for any guidance you can provide.

    Chuck

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Chuck,

    Ephemeral content like release notes and announcements don't follow the same process. This content is produced by program or product managers directly, not the Docs team. It's all a manual process. The Docs team will do an editorial review of the announcements in HC before they go public.

    Charles

    0
  • Scott Hudson
     

    For images (and other cross references), you might want to consider using @keyref instead of @href, then manage the paths to the images in a single key definition file. That way, when the path changes from your local system to some server path, you only have to update the keydef file instead of updating the paths on each of your topics.

    Scott

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Thanks, Scott. For those who want to learn more, see Indirect key-based addressing on www.oxygenxml.com.

    In our case, we use production urls in all DITA topics. If a linked article doesn't exist on HC yet, we create a placeholder article in Help Center to get its url. For images, we know what an image url on s3 will be if we know the image file name. Writers can also upload their images to s3 while an article is still in development to view the images in the article in Oxygen Author.

    This model is not for everyone. Most the members of the Docs team at Zendesk came from large software companies with more traditional production models. But in the SaaS industry like ours, the lines between contexts are getting blurred.

    0
  • Shay D.

    Hi Charles Nadeau 

    I'm trying out your create articles script and running into the same error as William Kellett, above.

    - Failed to create article with error 404: {"error":"RecordNotFound","description":"Not found"}

    This article does not exist in our HC, and I've double checked that all of the variables are correct. Everything seems correct (checked by doing print to screen) right up until the attempt to post the article in HC.

    Any suggestions?

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Shay,

    I assume you're referring to the gist at https://gist.github.com/chucknado/40ff923e6a2eef6ad529bf32cd12640f?

    The error could mean the API didn't find any of the following records in your account: author, section, user_segment, or permission_group.

    Double-check to make sure the values of the following variables in the script are all valid (I'm using '12345' as a placeholder):

    # settings
    author_id = '12345' # initial author of the articles
    section_id = '12345' # initial section of the articles
    user_segment_id = '12345' # initial user segment who can view the articles
    permission_group_id = '12345' # initial group who can edit and publish the articles

    For example, you must specify the user id of an existing user in your account as the author_id. The script won't create the user.

    2
  • Shay D.

    Hi Charles,

    Thank you for your reply. Yes, I meant the gist. 

    Yesterday I revalidated all the variables, and discovered that I had the wrong permission_group_id. Once I changed that, the script worked perfectly.

    Thanks again!

    0
  • Maria Kopylova

    Hello, Charles!

    Could you please show the proper examples of handoff,json and localized_content.json files? I am referring to your ZLO project on github. 

    I've found only the example of _custom_loader.json in the documentation.

    Thank you in advance. 

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Maria,

    I pushed example files to the docs folder in the repo. See example-handoffs.json and example-localized_content.json.

    Thanks.

    Charles

    1
  • Maria Kopylova

    Thank you, Charles. It really helped me a lot!

     

    Your project on GitHub is a brilliant and powerful tool for any knowledge base localization routine. I am so grateful for sharing it with us. 

    0
  • Valery Topilin

    Hi Charles,

    The described workflow requires a lot of manual operation and pasting HTML manually is killing the whole advantage of using DITA.

    Using API looks like a solution here, however when you're using DITA and you doing the batch transform of the articles into HTML there is no way to automatically produce an association between the HTML file and the SectionID where this article should belong. A workaround would be to create a reference file, as you mentioned - either in the format of the yml or csv, then parse it and upload the article. But this approach has different issue: when you add more articles to the section there is no way to identify which articles need to be updated and which need to be uploaded.

    Therefore it would be good to have an API smart enough to understand that if there is already an article in the section with the same name - update it, if not - upload it.

    Problem #2: Crosslinking.

    Some of the articles have links to other articles in the guide. Direct upload these HTMLs generated by DITA does break these links.

    I would like to hear how zendesk solved this issue?

    Theoretically to ensure that links are not broken it's possible to use API to store new Article IDs, then using a programmatic way to go through all of the articles, parse HTML, update links, and then update articles using the API again.

    Thank you!

    0
  • Charles Nadeau
    Zendesk Documentation Team

    Hi Valerie, thanks for the thoughtful comments.

    Problem #1: Publishing.

    > when you add more articles to the section there is no way to identify which articles need to be updated and which need to be uploaded.

    You could maintain a register of articles that includes both the DITA file name and corresponding HC article id of each article. Before publishing, the script could check the register. If the article is in the register, then it was published before and the script knows to use the Update Article endpoint using the recorded article id. If it's not in the register, then the script knows to use the Create Article endpoint instead. Because the endpoint returns the id of the new article, the script can then add the article to the register so it knows to make an update request next time. The register could be something as simple as a json or yml file.

    Problem #2: Crosslinking.

    > Some of the articles have links to other articles in the guide. Direct upload these HTMLs generated by DITA does break these links.

    If I understand the question, you're referring to using DITA file names and resource ids in xrefs to other articles? Something like:

    <xref href="themes_working.dita#topic_v4p_gyk_chb">

    Our team uses Help Center URLs in xrefs to other articles, bypassing the problem. We do use DITA resource ids for anchor links and these carry over in the transformation without breaking.

    As you mention, you could also programmatically go through all the articles, parse HTML, update links, and then update articles using the API again.

    We use this method to update links and images in article translations when they come back from the translators. All the urls in the translations still point to English articles. So we maintain a JSON inventory of all localized articles and images. It was created initially with the Translations API but now we update it on an ongoing basis as we get translations back. The script uses it to parse the translations and replace the href and src values.

     

    0

Please sign in to leave a comment.

Powered by Zendesk