Location of Page Template object from inside a macro - zope

Is there a way to get the object in which a defined macro is located?
I know that in a Zope Page Template, I have access to the "template" variable, which always points to the Page Template that was called in the first place. This variable can even be accessed inside macros or even nested macros called from the Page Template.
But sometimes it would be handy to be able to evaluate the object where the macro code resides in, for example to get its id or some other attributes or properties.
Example:
Page Template "first_template":
<tal:block metal:use-macro="/path/to/mymacroobject/macros/mymacro">
Macro
</tal:block>
Page template "macroobject" with the called macro:
<tal:block metal:define-macro="mymacro">
This macro was called from the template <strong>${template/getId}<strong> located at ${template/absolute_url}.
But I have no idea where I'm located or even what my id is.
</tal:block>
Rendering:
This macro was called from the template first_template located at /some/path/first_template. But I have no idea where I'm located or even what my id is.
Is there any way to access the object containing the macro code from inside the macro?

Related

Delete File From Word Templates Startup Folder

I have a template (dotm) file in the word startup folder -C:\Users(username)\AppData\Roaming\Microsoft\Word\STARTUP.
I want to have a macro (vba code) in this dotm file that delete this template from the startup folder. The template is an add-in with custom RibbonXML. I want one of my buttons to be "uninstall" button, which deletes the template file from the startup folder.
What you envision is not possible.
In order for the macro in the template to run, that template must be open or loaded as an add-in. In that case, there's a "file lock" on the template: it cannot be moved or deleted.
Deleting the template must be done from code that is not associated with the template, when the template is closed and there is no longer a file-lock.
Edit based on new information edited into the question
Possibly, code in another file could do this, although it's not certain the file lock will be released in a timely manner after the Unload method removes it from Word. It might require running code on a Timer to repeat the Kill command until it's successful.
Use the idQ attribute for the RibbonX tab/group that will contain the "Uninstall" button. This lets other RibbonX share the tab/group by using the same idQ value. Put the Ribbon XML defining that button, as well as the code for it, in the other file. When both files' Ribbons are loaded it will appear to the user as one Ribbon.
The startup template would load this other file as an add-in using the method Application.AddIns.Add.

Load macros from dotm

The scenario:
When word starts, it connects via vba to a Service, which returns a list of paths. Each of These paths points to a .dotm file. These files contain information about various controls (inside the ribbon, for example a butto which adds a specific footer).
What I want: I need a possibility to load several .dotm files, but without copying or moving them to a specific location.
Basically that's it. I've searched wide and far and I have the fear, that this Approach is actually not possible, and that I have to copy all dotm files inside the startup-folder and let word do the rest
Is there any way how I can load several dotm files into a single word-file, so that the ribbon gets extended depending on the dotm's
Best regards, please and thanks :)
From word documentation:
This example attaches the template "Letter.dot" to the active document.
ActiveDocument.AttachedTemplate = "C:\Templates\Letter.dot"
You can use this to attach all your templates to the document.
See also the Templates collection.
you can add a template to the Templates collection by using the Add method with the Addins collection to load a global template
Sub AddTemplate()
' For this example to work correctly, verify that the
' path is correct and the file exists.
AddIns.Add FileName:="C:\Program Files\Microsoft Office" _
& "\Templates\Letters & Faxes\MyFax.dot", Install:=True
End Sub
It's not possible to load multiple templates to a single Word file. Only one template can be attached to a document.
It is possible to load multiple templates as add-ins in the Word environment. These will be available then to all documents opened in the Word application. Use the Addins-Add method to add a template to the list in Document/Document Template, the "Global templates and add-ins" list. (This is the equivalent of the "Add" button in the dialog box.)
Dim bInstalled as Boolean
Dim Path as String
Dim fileName as String
'Populate the variables, then...
Application.Addins.Add Filename:=Path & fileName, Install:=bInstalled
Set bInstalled to false if you want the template in the list, but not loaded (Ribbon isn't displayed, for example); set it to true to also load it. Once a template is in the list, whether loaded or unloaded, it will generally remain in the list unless Word is reset in some manner. The code for managing template add-ins would be more efficient if it first checks whether an Add-in is already in the list before adding it again.
Templates that are in the list can be loaded/unloaded using the Addins.Installed property. If the tools in a template should be available only to certain documents then they can be loaded/unloaded dynamically by using events, such as DocumentChange.
The code to load the add-ins and manage them (events) should probably be in a central template in Word's Startup folder or in the template attached directly to the document.

No Access to Template's Document

I have an existing Macro Enabled Template which I would like to add Content Control to, to be available on the screen when the Template is accessed.
I know how to add the Content to a Word Document and then save it as a Template. The problem is that I cannot view the Exisiting Template's Word Document due to the view Object being greyed out. See below:
I really do not want to copy all my Macros and my quick texts over to a new document just to add one line of text and a button.
I can easily add the required text and CommandButton by having a script run in a Document_New Sub under the ThisDocument. The problem is that this Sub bombs out due to Macros not being enabled. I intend to have the Template distributed to numerous colleagues, therefore having the Text and button on the document will avoid any confusion as to what to do with the template.
You need to open the Template via File - Open
Opening the Template this way will display give you access to the Template.
For info: The name of the Template will appear in the Center of the Word Application.

Centralized VBA code for multiple Word files

I have multiple files with the same VBA code in them, which will most likely have to be changed over time. I don't want to go one by one and c/p the code, so one obvious idea that came to mind is to have one centralized document with the code (template?) that all files refer to.
I found a few topics here at stackoverflow, but none of them work for me or are inconclusive:
Run external vba-code in MS Word
Centralized VBA code (one file) for multiple workbooks
Calling an External VBA from VBScript
Any ideas?
Yes, your idea of centralizing the code in a template and attaching that template to the various Word docs will work. These pics are using Word 2007 but I think it's pretty similar for newer versions. First create a new document and put the code in a Module (named "CommonFunctions" in the picture):
Save the doc as a macro-enabled template:
Now make a new document, save it as a *.docm (necessary for it to run code because a *.docx is macro-free), and attach the document template as shown below. (An alternative is to put the *.dotm file in the startup directory C:\Users\<username>\AppData\Roaming\Microsoft\Word\STARTUP, which loads it automatically.) If you don't put it in the Startup, you'll see the name but it won't be loaded (ie, checked), but you can load it in code, as I'll show.
Make a user form in this document:
Put this code for the button's click event:
If AddIns("c:\_b\MasterDocWithFunctions.dotm").Installed = False Then
AddIns("c:\_b\MasterDocWithFunctions.dotm").Installed = True
End If
Application.Run "CommonFunctions.Test1"
Application.Run "CommonFunctions.Test2"
Notice how the code can load the AddIn for you, because it won't be automatically loaded unless you put it in the Startup directory. This pic shows how the AddIn is referenced but not loaded. You need the checkbox to be able to call code in it. If you don't load it using code and don't put it in the Startup, then the user will have to manually put a checkmark everytime the document opens.
Now the form should work when you click the button. Notice how it can call both public and private functions. The Private keyword definitely shields one module from another, but it seems like modules that are called from an AddIn are considered to be part of the same module, not sure why? Also if you don't put Public or Private at all then VBA considers it Public, I'm pretty sure.

Exclude template reference and macros from document

I am creating a template which has some macros inside. What the macros do is to open a user form which will prompt the user for some information which will then go into the new document.
The problem is that once the new document is created, it still somehow have a reference to this template and the macro code.
I have to send the document to people outside of the organization and they get a warning that the document contains macros.
Is there a way to avoid this? I want the document to be created without any of the macros or referrence to the original template.
Try creating the new document with "Normal" as a parameter for the Documents.Add method. The default seems to be to create a document off of the current open template (or Normal if none).