Unable to correctly programmatically declare server-based TMs

I'm trying to programmatically add server-based TMs to a project, but am unable to.

Having read through this thread I have the following code

    public void AddServerBasedTM(FileBasedProject project, Language targetLanguage, ServerBasedTranslationMemory serverTM)
    {
        var tmConfig = project.GetTranslationProviderConfiguration();

        tmConfig.Entries.Add(new TranslationProviderCascadeEntry(new TranslationProviderReference(serverTM.Uri,
                                                                                                  serverTM.SerializeState(),
                                                                                                  true),
                                                                 true,
                                                                 true,
                                                                 true,
                                                                 0));
                                                                
        project.Credentials.AddCredential(serverTM.Uri, $"user=[...];password=[..];type=CustomUser");

        project.UpdateTranslationProviderConfiguration(targetLanguage, tmConfig);
        project.AddMasterTM(tmConfig, targetLanguage.IsoAbbreviation);
        project.Save();
    }

The above code results in the following being added to the .sdlproj file:

    <LanguageDirections>
        <LanguageDirection Guid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" SettingsBundleGuid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TargetLanguageCode="en-GB" SourceLanguageCode="de-CH">
            <AutoSuggestDictionaries />
            <CascadeItem OverrideParent="false" StopSearchingWhenResultsFound="false">
                <CascadeEntryItem PerformConcordanceSearch="true" Penalty="0" PerformUpdate="true" PerformNormalSearch="true">
                    <MainTranslationProviderItem Uri="sdltm.my.server.url/groupshare" Enabled="true" />
                </CascadeEntryItem>
            </CascadeItem>
        </LanguageDirection>
    </LanguageDirections>

However, upon opening the project no TMs appear to be referenced (either under "All Language Pairs" or under the specific pairing):

Parents
  • I think I can see where the problem is, but I'm not sure why this is a problem or how I should correct this.

    After a bit (lot) of trial and error, and comparing with a project created from a template (in which the TM appears to be correctly referenced) I've narrowed down the problem area to two <CascadeItem> nodes in the project file.

    There are two of these nodes in the .sdlproj file:

        <CascadeItem OverrideParent="false" StopSearchingWhenResultsFound="false" />

    and

        <CascadeItem OverrideParent="false" StopSearchingWhenResultsFound="false">
           <CascadeEntryItem PerformConcordanceSearch="true" Penalty="0" PerformUpdate="true" PerformNormalSearch="true">
             <MainTranslationProviderItem Uri="sdltm.my.server.url/groupshare Enabled="true" />
           </CascadeEntryItem>
        </CascadeItem>


    Now, in the project for which the TM shows up in Trados, the smaller/first of the two <CascadeItem> variants shows up inside the <LanguageDirection> node; the larger/second of the two <CascadeItem> nodes is included farther through the file and is a top-level element (i.e., directly under the <Project> root).

    However, in the version which I created using the code in the previous post, these two <CascadeItem> elements are switched around, i.e., the smaller is a top-level element and the larger is a child of the <LanguageDirection> node.

    I've found that if I manually switch them back then the TM appears to be correctly referenced when the project is opened in Trados.

    I've realised that calling

        project.UpdateTranslationProviderConfiguration(targetLanguage, tmConfig);

    with a specified target language is what moves the TM into the <LanguageDirection> element, and that calling the overload of this method without a target language will record the TM in a top-level <CascadeItem> node. If I open this project locally then everything looks good. However, if I upload this project to GroupShare and open from there then no TMs are referenced. Upon opening the downloaded-from-GroupShare project file I can see that the larger <CascadeItem> element which should contain the TM paths has been replaced with the shorter, simpler element without the paths - this shorter version then appears twice in the project file.

    A couple of final notes:

    • when creating the project I'm specifying the following ProjectPackageCreationOptions

          IncludeAutoSuggestDictionaries = false,
          IncludeMainTranslationMemories = true,
          IncludeTermbases = true,
          RemoveAutomatedTranslationProviders = true,
          RecomputeAnalysisStatistics = true,
          ProjectTranslationMemoryOptions = ProjectTranslationMemoryPackageOptions.CreateNew,
          RemoveServerBasedTranslationMemories = false

    • although I'm calling

          project.Credentials.AddCredential(uri, $"user=...;password=...;type=CustomUser");

      These credentials don't appear in the project file.

    My suspicion now is that the missing credentials might be preventing GroupShare from doing some processing that needs to be done upon upload.

    Nonetheless I'm still in the situation of being unable to programmatically add TMs to a project.

  • I came across this post when investigating why the PowerShell Toolkit sample script does not work (i.e. behaves exactly the same).
    The trick is that you need to set tmConfig.OverrideParent property to true before calling "UpdateTranslationProviderConfiguration" to make the configured language-specific TMs appear in the project settings.

Reply Children
No Data