# Resaving Templates

Two ways to resave templates in an org.

{% stepper %}
{% step %}

### Resaving Templates Using a SOQL Query

* This statement will resave all templates within an org.
* Support will provide the following statement along with a warning about running this in an org with many templates because it could lock down the org.

```
update [SELECT Id FROM SDOC__SDTemplate__c WHERE SDOC__Active__c=true];
```

* For updating more than 50 templates, you will want to use a limit and offset for each chunk of 50. The limit will always be 50, the offset will be whatever row the last updated ended at (No offset for first 50, offset of 50 for rows 51-100, etc.). Example:

```
update [SELECT Id FROM SDOC__SDTemplate__c WHERE SDOC__Active__c=true LIMIT 50 OFFSET 50];
```

{% endstep %}

{% step %}

### Resaving Templates Using an Apex Class and a VisualForce Page

* This statement will resave all templates within an org.
* This Apex class and VF page is the best route for resaving templates (usually after an upgrade)
  * It needs to be manually invoked
* It will update the Last Modified Date for the templates

#### VisualForce Page

```
<apex:page controller="SDocBulkUpdateController">
    <apex:form >
        <apex:actionFunction name="runBulkUpdate" action="{!runBulkUpdate}" oncomplete="console.log('updated a few templates...');runBulkUpdateOncomplete();" reRender="mainPanel" />
        <apex:outputPanel id="mainPanel">
            <script>
                function runBulkUpdateOncomplete() {
                    if (parseInt('{!currentOffset}') > parseInt('{!numTemplatesToUpdate}')) {
                        alert('Done updating templates');
                        return;
                    }
                    runBulkUpdate();
                }
            </script>
            <apex:commandButton value="Begin Bulk Update" onclick="runBulkUpdate();" disabled="{!currentOffset > 0}" reRender="mainPanel" />
            <br />
            {!numTemplatesToUpdate} templates total.<br />
            {!numTemplatesIterated} templates iterated through so far.<br />
            {!numTemplatesRemaining} templates remaining.<br />
            Made edits to the following templates: <br />
            <apex:outputText escape="false" value="{!editedTemplateIds}" />
        </apex:outputPanel>
    </apex:form>
</apex:page>
```

#### Apex Class

```
public class SDocBulkUpdateController {

    // EDIT THESE TWO STRINGS. DO NOT EDIT ANYTHING ELSE
    public final String TO_REPLACE = '<p><span style="color:white;">.</span></p>';
    public final String REPLACEMENT_STR = '<p class="SDBulkEditP">&nbsp;</p>';

    public Integer currentOffset {get;set;}
    public static final Integer OFFSET_LIMIT = 10;
    public List<String> editedTemplateIds {get;set;}
    public final Integer numTemplatesToUpdate {get;set;}
    public Integer numTemplatesIterated {get;set;}
    public Integer numTemplatesRemaining {get;set;}

    public SDocBulkUpdateController() {
        currentOffset = 0;
        editedTemplateIds = new List<String>();
        numTemplatesToUpdate = Database.query(getBaseQuery()).size();
        numTemplatesRemaining = numTemplatesToUpdate;
        numTemplatesIterated = 0;
    }

    public static String getBaseQuery() {
        return 'SELECT Id, Name, ' + getTemplateXMLFieldsForQuery(false) 
            //+ String.join(getMarginFields(), ',')
            + ' FROM SDOC__SDTemplate__c '
            + ' WHERE SDOC__Active__c=true';
    }

    /*public List<String> getMarginFields() {
        return new List<String>{
            'SDOC__MS_Page_Header_Margin__c',
            'SDOC__MS_Page_Footer_Margin__c',
            'SDOC__MS_Page_Margin_Left__c',
            'SDOC__MS_Page_Margin_Right__c'
        };
    }*/
    
    public void runBulkUpdate() {
        if (currentOffset > numTemplatesToUpdate) return;
        //List<String> marginFields = getMarginFields();
        // Decrease offsetLimit if Apex Heap Size error persists
        List<SDOC__SDTemplate__c> templates = Database.query(
            + getBaseQuery()
            + ' LIMIT ' + OFFSET_LIMIT  + ' OFFSET ' + currentOffset);
        List<SDOC__SDTemplate__c> templatesToUpdate = new List<SDOC__SDTemplate__c>();
        for (SDOC__SDTemplate__c sdt : templates) {
            String templateXML = concatenateTemplateXMLFields(sdt);

            if (templateXML.contains(TO_REPLACE)) {
            
                templateXML = templateXML.replace(TO_REPLACE, REPLACEMENT_STR);
                
                populateTemplateXMLFields(sdt, templateXML);
                templatesToUpdate.add(sdt);
                editedTemplateIds.add('<a href="/apex/SDOC__SDTemplateEditor?id=' + sdt.Id + '" target="_blank">' + sdt.Name + '</a>');
            }
            // For each margin field, change it to 0 if it was set to a negative value
            /*for (String mf : marginFields) {
                if (Decimal.valueOf(sdt.get(mf)) < 0) {
                    sdt.put(mf, 0);
                }
            }*/
        }
        update templatesToUpdate;
        currentOffset += OFFSET_LIMIT;
        numTemplatesIterated += templates.size();
        numTemplatesRemaining -= templates.size();
        if (currentOffset > numTemplatesToUpdate) return;
    }

    public static String getTemplateXMLFieldsForQuery(Boolean encode) {
        String fields = ''
            + 'SDOC__Template_XML__c, '
            + 'SDOC__Template_XML2__c, '
            + 'SDOC__Template_XML3__c, '
            + 'SDOC__Template_XML4__c, '
            + 'SDOC__Template_XML5__c, '
            + 'SDOC__Template_XML6__c, '
            + 'SDOC__Template_XML7__c, '
            + 'SDOC__Template_XML8__c, '
            + 'SDOC__Template_XML9__c, '
            + 'SDOC__Template_XML10__c ';
        if (encode) fields = fields.replace('XML', 'XML_Encode');
        return fields;
    }

    public static String concatenateTemplateXMLFields(SDOC__SDTemplate__c t) {
        String templateXML = t.SDOC__Template_XML__c;
        if (templateXML==null)
            templateXML='';
        if (t.SDOC__Template_XML2__c!=null)
           templateXML += t.SDOC__Template_XML2__c;
        if (t.SDOC__Template_XML3__c!=null)
           templateXML += t.SDOC__Template_XML3__c;
        if (t.SDOC__Template_XML4__c!=null)
           templateXML += t.SDOC__Template_XML4__c;
        if (t.SDOC__Template_XML5__c!=null)
           templateXML += t.SDOC__Template_XML5__c;
        if (t.SDOC__Template_XML6__c!=null)
           templateXML += t.SDOC__Template_XML6__c;
        if (t.SDOC__Template_XML7__c!=null)
           templateXML += t.SDOC__Template_XML7__c;
        if (t.SDOC__Template_XML8__c!=null)
           templateXML += t.SDOC__Template_XML8__c;
        if (t.SDOC__Template_XML9__c!=null)
           templateXML += t.SDOC__Template_XML9__c;
        if (t.SDOC__Template_XML10__c!=null)
           templateXML += t.SDOC__Template_XML10__c;
        return templateXML.replace('¦', ' ');
    }

    public static void populateTemplateXMLFields(SDOC__SDTemplate__c t, String templateXML) {
        integer l = templateXML.length();
        if (l>320000)
            t.SDOC__Template_XML10__c= splitter(templateXML.substring(288000,320000));
        if (l>288000 && l<=320000)
            t.SDOC__Template_XML10__c= splitter(templateXML.substring(288000,l));
        if (l>288000)
            t.SDOC__Template_XML9__c= splitter(templateXML.substring(256000,288000));
        else
            t.SDOC__Template_XML10__c= '';
        if (l>256000 && l<=288000)
            t.SDOC__Template_XML9__c= splitter(templateXML.substring(256000,l));
        if (l>256000)
            t.SDOC__Template_XML8__c= splitter(templateXML.substring(224000,256000));
        else
            t.SDOC__Template_XML9__c= '';
        if (l>224000 && l<=256000)
            t.SDOC__Template_XML8__c= splitter(templateXML.substring(224000,l));
        if (l>224000)
            t.SDOC__Template_XML7__c= splitter(templateXML.substring(192000,224000));
        else
            t.SDOC__Template_XML8__c= '';
        if (l>192000 && l<=224000)
            t.SDOC__Template_XML7__c= splitter(templateXML.substring(192000,l));
        if (l>192000)
            t.SDOC__Template_XML6__c= splitter(templateXML.substring(160000,192000));
        else
            t.SDOC__Template_XML7__c= '';
        if (l>160000 && l<=192000)
            t.SDOC__Template_XML6__c= splitter(templateXML.substring(160000,l));
        if (l>160000)
            t.SDOC__Template_XML5__c= splitter(templateXML.substring(128000,160000));
        else
            t.SDOC__Template_XML6__c= '';
        if (l>128000 && l<=160000)
            t.SDOC__Template_XML5__c= splitter(templateXML.substring(128000,l));
        if (l>128000)
            t.SDOC__Template_XML4__c= splitter(templateXML.substring(96000,128000));
        else
            t.SDOC__Template_XML5__c= '';
        if (l>96000 && l<=128000)
            t.SDOC__Template_XML4__c= splitter(templateXML.substring(96000,l));
        if (l>96000)
            t.SDOC__Template_XML3__c= splitter(templateXML.substring(64000,96000));
        else
            t.SDOC__Template_XML4__c= '';
        if (l>64000 && l<=96000)
            t.SDOC__Template_XML3__c= splitter(templateXML.substring(64000,l));
        if (l>64000)
            t.SDOC__Template_XML2__c= splitter(templateXML.substring(32000,64000));
        else
            t.SDOC__Template_XML3__c= '';
        if (l>32000 && l<=64000)
            t.SDOC__Template_XML2__c= splitter(templateXML.substring(32000,l));                    
        if (l>32000)
            t.SDOC__Template_XML__c = splitter(templateXML.substring(0,32000));
        else{
            t.SDOC__Template_XML2__c= '';
            t.SDOC__Template_XML__c = templateXML;
        }
    }

    public static string splitter(string str){
        if (str == null) { return null; }
        if (str.substring(0,1) ==' ')
            str= '¦'+str.substring(1,str.length());
        if (str.substring(str.length()-1,str.length())==' ')
            str= str.substring(0,str.length()-1) +'¦';
        return str;
    }

    public class SDException extends exception {}
}
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.sdocs.com/sdocs/administration/landing-page-for-admin/additional-troubleshooting/resaving-templates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
