In today’s fast-paced digital environment, the demand for accurate, consistent, and timely product information is paramount. Traditional methods of technical documentation, often reliant on manual processes and disparate tools, fall short in meeting these demands. This is where PTC Arbortext emerges as a game-changer. It offers a dynamic publishing solution that streamlines the creation, management, and delivery of technical content.

 

The Pitfalls of Traditional Documentation Methods

Many businesses rely on one or two technical writers to collect all required technical and digital information needed to create technical and marketing publications. Most of this effort is manual, using the tried and true method of emailing, calling, and walking down the hall to bug technical resources for information or a screen grab; over and over. Then the information is created using a one-and-done single-instance authoring software like Adobe FrameMaker, Adobe InDesign, or Microsoft Word.

This is a problem for a number of reasons, including:

  • Inconsistencies and Errors: Manual data collection can lead to outdated or incorrect information permeating through various documents.​
  • Inefficiencies: Repetitive tasks and lack of automation slow down the documentation process, delaying product releases.​
  • Scalability Issues: As products become more complex, managing documentation manually becomes increasingly untenable.

Just think of everywhere incorrect information could live if an update is missed. Web sites, user manual libraries, manufacturing instructions, service instructions, printed manuals, marketing literature, and the list goes on. This can increase the risk of providing out-of-date or inaccurate information to customers, manufacturing personnel, and service technicians.

    Embracing Dynamic Publishing with Arbortext

    PTC Arbortext offers a comprehensive solution to these challenges by enabling dynamic publishing. This method automates and integrates the entire documentation lifecycle. Key benefits include:​

    • Single Source of Truth: Centralize content to ensure consistency across all documentation.​
    • Automated Updates: Link documentation directly to product data, allowing automatic updates when changes occur.​
    • Multi-Channel Delivery: Publish content across various formats and platforms without redundant efforts

    Core Components of the Arbortext Suite

    When arguing for Arbortext, there’s strength in overarching capabilities. However, there’s also the power and precision of its individual components. Like many other PTC product lines, Arbortext boasts a suite of several integrated tools. This robust ecosystem of tools work together to streamline structured content creation, styling, and publishing. This empowers technical teams to do more, faster, and with fewer errors. These extensions have been designed to enhance the documentation process. They include:​

    • Arbortext Editor: A powerful, XML-based authoring tool designed for creating structured content. It supports real-time validation, ensuring content conforms to required standards as it’s written. This not only improves accuracy but also reduces the need for post-creation corrections.
    • Arbortext Styler: A stylesheet design application that lets users visually create and manage styles for multiple output formats. Publishing to PDF, HTML, or EPUB? Styler allows organizations to control formatting rules without needing to write code, greatly simplifying the publishing process.
    • Arbortext Publishing Engine: The automation hub of the suite, this engine assembles, formats, and publishes content from Arbortext Editor using predefined styles and templates. It eliminates manual tasks and ensures consistent, repeatable publishing workflows across the enterprise.

    Together, these tools form a tightly integrated publishing solution. This solution enables organizations to maintain consistency, scale their documentation efforts, and reduce operational risk. Whether you’re a single author or managing a global documentation team, the Arbortext suite equips you with the foundation to build and deliver content that’s smart, structured, and future-ready.

    Integration with PTC Windchill for Enhanced Content Management

    One of the most compelling reasons to argue for Arbortext is its seamless integration with PTC Windchill, a leading product lifecycle management (PLM) system. This connection allows organizations to manage both product data and technical content within a single, unified platform. By linking Arbortext with Windchill, companies gain tighter control over content versioning, reuse, and approval processes, which is critical in regulated industries or highly complex product environments.

    Windchill serves as a single source of truth, ensuring that content creators always work with the most up-to-date product data and documentation. This reduces the risk of inconsistencies between product updates and technical materials—whether it’s a service manual, part catalog, or training content. Integration also supports granular access control, workflow automation, and traceability, helping teams stay audit-ready and in compliance.

    Together, Arbortext and Windchill form a powerful digital thread that connects engineering, manufacturing, and documentation teams across the entire product lifecycle. This integration not only accelerates content creation and delivery but also reinforces data integrity and operational efficiency, making it a cornerstone argument in favor of adopting Arbortext for dynamic publishing.

    Real-World Impact: Efficiency and Accuracy

    When arguing for Arbortext, it’s essential to look beyond features and focus on real-world outcomes. Organizations that implement Arbortext experience measurable gains in both operational efficiency and content accuracy. By automating manual processes like formatting, layout, and publication, teams spend less time on repetitive tasks and more time on high-value content creation. This leads to faster documentation cycles and reduced time-to-market for products.

    Dynamic publishing ensures that information is consistent across all deliverables, minimizing the risk of errors or outdated content reaching end users. Technical writers can generate multilingual, multi-format documents in a fraction of the time it would take using traditional tools, and updates can be made globally with just a few clicks.

    Ultimately, Arbortext isn’t just about creating content—it’s about transforming how content is managed, updated, and delivered throughout the organization. These efficiency and accuracy gains drive real business value, making a strong, results-based case for integrating Arbortext into your enterprise content strategy.

    Making the Case for Arbortext

    In an era where information accuracy and speed are critical, arguing for Arbortext becomes a matter of strategic importance. Making the move from manual technical publications to what we just described allows tech writers to focus on optimization of publishing methods rather than data collection and integration. It helps insure overall accuracy of product data throughout the company and in the marketplace. By transitioning to dynamic publishing with PTC Arbortext, organizations can overcome the limitations of traditional documentation methods, ensuring that their technical content is accurate, consistent, and delivered efficiently across all platforms.

      Having more technical illustrations than information is beneficial in many ways—and the solution to do so is easier than you think.

      Here’s why you should be using more technical illustrations and the best way to create them.

      Technical Illustrations are Easy to Understand

      We all know the saying “ a picture paints a thousand words”—and in this case, it’s more than true.

      It’s much easier to interpret a picture than to understand and read through lots of text. Using illustrations in tech pubs, user manuals, and service manuals reduce user errors.

      Illustrations Take Away the Need for Text

      Have you ever bought anything from Ikea? Sure you have! They sell their flat pack furniture all over the globe using the same manuals. That is the power of illustrations. You can drastically reduce the amount of text that is needed by producing illustrations.

      Using Technical Illustrations Reduces the Need for Translation

      With less text that is needed or used, you can reduce your translation costs.

      So Why Doesn’t Everyone Use Illustrations?

      The traditional process to create illustrations is time-consuming and can be froth with problems.

      Let me illustrate it for you.

      Odds are if you are using the traditional illustration process, your technical illustrators most likely work with engineers to get snapshots of CAD information to use in illustrations.

      These snapshots are usually static because they are captured at only a moment in time, usually near the end of the product development process.

      Because the illustrations are static, they are not always easy to interpret. This means the text is still required to properly convey the information.

      If your snapshots were taken at the end of the product development process because there was ‘ less likelihood of the product changing’ – you could be delaying your shipment process.

      Often a product cannot ship until the technical information that is associated with it is ready to ship with the product.

      Now consider all the back and forth communication between both the engineering department and the illustration group.

      Traditional illustrations are difficult to keep up to date. Commonly the illustrator needs to go back to the engineer for updates every time there is a change to the product.

      If at any time there is a miscommunication, your illustrations could easily become inaccurate; exposing your organization to the risk of unsatisfied customers, frustrated field technicians, and the possibility of lawsuits.

      It’s easy to see why the traditional methods to create illustrations are downright time consuming and prone to error.

      So How Can You Make Technical Illustrations Easily?

      The answer is Creo Illustrate.

      Creo Illustrate leverages CAD data to create illustrations that, depending on your PDM/PLM setup, maintain an associative link to the original CAD data.

      This means any changes you make with your CAD data can automatically update all your illustrations and possibly your publications.

      With Creo Illustrate you have the ability to start creating illustrations early on in the product development process, with a guarantee that your illustrations are always kept up-to-date. Start developing product documentation during the product development process instead of after the product development process.

      See Creo Illustrate in action! Watch this short video.

      One of the great aspects of ThingWorx is the ability to connect disparate data silos to a central IoT hub. Many of these silos are made accessible through Web APIs. RESTful Web APIs enable developers to pull data from an inexhaustible number of sources around the web; often using nothing but a HTTP URI. Salesforce has an extensive REST API that can be accessed through ThingWorx. This blog will introduce you to creating a “Connected App” on Salesforce, authentication using username and password in ThingWorx, adding records to Salesforce, and finally modifying records. For a detailed description of Salesforce’s REST API, visit https://developer.salesforce.com/page/REST_API

      Step 1 (Optional): Obtain a Developer Environment with Salesforce.com

      If you do not already have a Salesforce account, navigate to https://developer.salesforce.com/platform/force.com and sign up for a free developer environment. It only takes a few minutes and you get a fully functioning Salesforce instance that you can freely develop in.

      Step 2: Obtain a Security Token

      You’ll need a security token to authenticate with a username and password. If you don’t already have one, or can’t dig it up from previous emails, you’ll need to reset the token.

      Resetting the Token

      1.    In the upper right-hand corner of your Salesforce page, click on your name and select “My Settings”

      2.    On the left-hand menu, select “Personal”

      3.    Under “Personal,” select “Reset My Security Token”

      4.    Follow the directions on the page and you will receive a new security token via email

      Step 3: Create a Connected App

      To use the REST API, we’ll need to create a connected app that gives us a “Consumer Key” and a “Consumer Secret”.

      Creating the Connected App

      1.    Click on “Settings” in the upper right of your Salesforce screen

      2.    On the left side, navigate to “Build” > “Create” > “Apps”

      3.    Under the “Connected Apps” section, select “New”

      4.    Fill out the fields as shown below. A callback URL is required but we won’t really be referencing it anywhere in ThingWorx. There is a great article on using Postman to test out REST calls with Salesforce at https://blog.mkorman.uk/using-postman-to-explore-salesforce-restful-web-services/ . The callback URL is used in the examples when authenticating in Postman.

      5.    Click “Save.” You will get an alert that your connected app will take 2-10 minutes to take effect.

      6.    After you click “Save,” you’ll see the “Consumer Key” and “Consumer Secret.” Copy those somewhere to use in ThingWorx.

      Step 4: Authenticate Salesforce Session in ThingWorx

      In this step, we’ll create a service in ThingWorx that returns a JSON for us to use in our other Salesforce requests.

      1.    Create a service inside your Thing called AuthenticateSalesForce. I have a “TestThing” that I’ve created where I can try out new services without disrupting any of my live projects.

      2.    Choose the “STRING” type for the result output, no inputs are needed unless you want to have the end user input their username and password. After we test functionality, we’ll change the output type to “JSON”

      3.    Enter the following code, which is just the POST JSON function in the ContentLoaderFunction resource.

      var params = {
      
                       proxyScheme: undefined /* STRING */,
                       headers: undefined /* JSON */,
                       ignoreSSLErrors: undefined /* BOOLEAN */,
                       useNTLM: undefined /* BOOLEAN *
                       workstation: undefined /* STRING */,
                       useProxy: undefined /* BOOLEAN */,
                       withCookies: undefined /* BOOLEAN */,
                       proxyHost: undefined /* STRING */,
      
      url: "https://login.salesforce.com/services/oauth2/token?grant_type=password&client_id=&client_secret=&username= &password=" /* STRING */,
      
                       content: undefined /* JSON */,
                       timeout: undefined /* NUMBER */,
                       proxyPort: undefined /* INTEGER */,
                       password: undefined /* STRING */,
                       domain: undefined /* STRING */,
                       username: undefined /* STRING */
      
      };
      
      // result: JSON
      var j = Resources["ContentLoaderFunctions"].PostJSON(params);
      
      var result = j.access_token;

      4.    Enter the consumer key, consumer secret, username (use %40 for the ‘@’ symbol), and password plus security token (enter your password and security token with no spaces between the two)

      5.    Select “Done” on your service, save your Thing, and test the service. You should receive a session token like the one seen below:

      6.    If nothing shows up, either the Salesforce server hasn’t activated the app, or there may be an issue with the URL. If you copy and paste the URL into PostMan, you should get an error message that clarifies the issue.

      7.    When you’re getting an access token as the result, edit your service, change the result type to “JSON,” delete the last line (the “var result = j.access_token” line”), and modify the end of the service to now read:

      // result: JSON

      var result = Resources[“ContentLoaderFunctions”].PostJSON(params);

      Step 5: Create a record in Salesforce

      In this step, we’ll create a new account within salesforce using our new authentication service and a REST call utilizing the ContentLoaderFunctions.

      1.    Create another new service in your Thing and call it AddSalesForceAccount. 2.    Create an input and call it AccountName. The type is “STRING” 3.    Type in the following code:

      var authJSON = me.AuthenticateSalesForce();
      
      var token = authJSON.access_token;
      var instance_url = authJSON.instance_url;
      
      var url = instance_url + "/services/data/v20.0/sobjects/Account/";
      
      var authString = "Bearer " + token;
      var headers = {
         "authorization" : authString,
         "content-type" : "application/json"
      };
      
      var content = {
       "Name" : AccountName
      };
      
      var params = {
                       proxyScheme: undefined /* STRING */,
                       headers: headers /* JSON */,
                       ignoreSSLErrors: undefined /* BOOLEAN */,
                       useNTLM: undefined /* BOOLEAN */,
                       workstation: undefined /* STRING */,
                       useProxy: undefined /* BOOLEAN */,
                       withCookies: undefined /* BOOLEAN */,
                       proxyHost: undefined /* STRING */,
         url: url /* STRING */,
                       content: content /* JSON */,
                       timeout: undefined /* NUMBER */,
                       proxyPort: undefined /* INTEGER */,
                       password: undefined /* STRING */,
                       domain: undefined /* STRING */,
                       username: undefined /* STRING */
      };
      
      // result: JSON
      var result = Resources["ContentLoaderFunctions"].PostJSON(params);

      4. Test the service. Enter a unique account name and verify that it shows up in Salesforce.

      Step 6: Retrieve a Record ID

      To modify a record, the record ID must be used to reference the object of interest. We can make a request to Salesforce to return relevant records using an SOQL query. This example will cover retrieving the record ID of the account we just created in the last step.

      1.    Create a new service in your Thing

      2.    Create an input and call it AccountName. The type is “STRING”

      3.    Type in the following code:

      var authJSON = me.AuthenticateSalesForce();
      
      
      var token = authJSON.access_token;
      var instance_url = authJSON.instance_url;
      
      var url = instance_url + "/services/data/v20.0/query/?q=SELECT+name+FROM+Account+WHERE+name+=+'" + AccountName + "'";
      
      var authString = "Bearer " + token;
      var headers = {
         "authorization" : authString,
         "content-type" : "application/json"
      };
      
      
      
      
      var params = {
                        proxyScheme: undefined /* STRING */,
                        headers: headers /* JSON */,
                        ignoreSSLErrors: undefined /* BOOLEAN */,
                        useNTLM: undefined /* BOOLEAN */,
                        workstation: undefined /* STRING */,
                        useProxy: undefined /* BOOLEAN */,
                        withCookies: undefined /* BOOLEAN */,
                        proxyHost: undefined /* STRING */,
                        url: url /* STRING */,
                        timeout: undefined /* NUMBER */,
                        proxyPort: undefined /* INTEGER */,
                        password: undefined /* STRING */,
                        domain: undefined /* STRING */,
                        username: undefined /* STRING */
      
      };
      
      
      
      
      // result: JSON
      var j = Resources["ContentLoaderFunctions"].GetJSON(params);
      
      var result = j.records[0].attributes.url;

      4. Give the service a name and test it. The output of this service is a url that can be appended to the instance_url that is returned in the response from the Authentication service.

      Step 7: Modify a Record

      Using the output from our last service, we can now easily modify the fields of the record ID that we just retrieved. Keep in mind, if you create a custom field and you want to modify its value, add a “__c” to the end of the field name (denotes custom field).

      1. Create a new service in your Thing
      2. Let’s give it a few “STRING” inputs: field, stringValue, and AccountName
      3. Input the following code:
      var authJSON = me.AuthenticateSalesForce();
      
      var token = authJSON.access_token;
      var instance_url = authJSON.instance_url;
      
      var stringJSON = '{"' + field + '":' + stringValue + "}";
      
      
      var params = {
                        AccountName: AccountName /* STRING */
      };
      
      // result: STRING
      var object_url = me.RetrieveSalesForceAccountRecordID(params);
      
      var url = instance_url + object_url + "?_HttpMethod=PATCH";
      var authString = "Bearer " + token;
      var headers = {
         "authorization" : authString,
         "content-type" : "application/json"
      };
      
      var content = JSON.parse(stringJSON);
      
      var params = {
                        proxyScheme: undefined /* STRING */,
                        headers: headers /* JSON */,
                        ignoreSSLErrors: undefined /* BOOLEAN */,
                        useNTLM: undefined /* BOOLEAN */,
                        workstation: undefined /* STRING */
                        useProxy: undefined /* BOOLEAN */,
                        withCookies: undefined /* BOOLEAN */,
                        proxyHost: undefined /* STRING */,
                        url: url /* STRING */,
                        content: content /* JSON */,
                        timeout: undefined /* NUMBER */,
                        proxyPort: undefined /* INTEGER */,
                        password: undefined /* STRING */,
                        domain: undefined /* STRING */,
                        username: undefined /* STRING */
      };
      // result: JSON
      var result = Resources["ContentLoaderFunctions"].PostJSON(params);

       

      A Note About Security

      Salesforce has a few ways to authenticate your session.  The method described in this blog is the least secure way because ThingWorx has visibility to the username and password of the Salesforce account.  There are two other ways to authenticate and both use callback URLs.  Basically, a user sends a call to the login endpoint and enters user and password information directly into the Salesforce environment.  Salesforce then redirects to a callback URL that is appended with an authorization token.  If you’d like to implement one of the more secure methods, I would suggest using a REST endpoint to a ThingWorx service as your callback URL. More specifically, create a service that has a string input called “code.” Now, change your callback URL in your Salesforce connected app to something like https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=&redirect_uri=>.  Now, when you navigate to the login link, it will send your authorization code to your ThingWorx service (this is because it appends “&code=” to the URL).  You’ll need to then send that code via the Content Loader Functions to receive your authorization token.  One thing to note is that the ThingWorx instance must be on HTTPS.  Salesforce does not allow HTTP callback URLs.  More information about Authentication can be found at https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_authentication.htm

      If you have any questions about this blog or ThingWorx in general, don’t hesitate to leave a comment or contact EAC Product Development Solutions.