Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
Content Modeling
For many content models, it is useful to have some data populated when the model is loaded. This is done by bootstrapping some data. One good example is in the Records Management module.
Importing the data in an import XML file or an ACP file as part of your modules initialization can be easily done.
<bean id='myModule.bootstrap'
class='org.alfresco.repo.module.ImporterModuleComponent'
parent='module.baseComponent'>
<property name='moduleId' value='myModule' />
<property name='name' value='myModuleBootstrap' />
<property name='description' value='My Modules initial data requirements' />
<property name='sinceVersion' value='1.0' />
<property name='appliesFromVersion' value='1.0' />
<property name='importer' ref='spacesBootstrap'/>
<property name='bootstrapViews'>
<list>
<props>
<prop key='path'>/${spaces.company_home.childname}</prop>
<prop key='location'>alfresco/module/myModule-123/myACP.acp</prop>
</props>
</list>
</property>
</bean>
Property Values
BootstrapViews
A list of the ACP or XML files to be imported and the location in the destination repository where the data should be imported.
Where you put them in the amp structure does not matter at all. What does matter is how you bootstrap it. Bootstrap code allows you to refer to an XML file that points to how nodes are supposed to be added.
You can add your information in one of two ways - in an XML file that points to files explicitly, or an ACP file (which also has an XML file that points to file, it's just easier to generate it through space export).
The easiest way to do this is:
1. Put your webscripts into the appropriate directory in data dictionary.
2. Delete ALL webscripts OTHER than yours.
3. Do an export of the contents of the directory. This will create an ACP file. Download the ACP file to your desktop and copy it to one of the module directories (e.g. bootstrap).
4. Create bootstrap-context.xml in context subdirectory of your module, i.e. config\alfresco\module\org.alfresco.module.yourmodule\context\
5. In the file, add a bean for bootstrapping, and point it to the ACP file:
<bean id='org_alfresco_module_bootstrapSpaces' class='org.alfresco.repo.module.ImporterModuleComponent' parent='module.baseComponent'>
<property name='moduleId' value='org.alfresco.module.yourmodule.project' />
<property name='name' value='org.alfresco.module.yourmodule.bootstrapSpaces' />
<property name='description' value='Initial data requirements' />
<property name='sinceVersion' value='0.4' />
<property name='appliesFromVersion' value='0.4' />
<property name='importer' ref='spacesBootstrap'/>
<property name='bootstrapViews'>
<list>
<props>
<prop key='path'>/cm:categoryRoot/cm:generalclassifiable</prop>
<prop key='location'>alfresco/module/org.alfresco.module.yourmodule/bootstrap/rm_categories.xml</prop>
</props>
<props>
<props>
<prop key='path'>/${spaces.company_home.childname}/${spaces.dictionary.childname}/cm:webscripts</prop>
<prop key='location'>alfresco/bootstrap/web_scripts.acp</prop>
</props>
</list>
</property>
</bean>
In the snippet above, web_scripts.acp should get exploded to Web Scripts directory: since alfresco parses xpath expressions the correct path to the Web Scripts folder is /cm:webscripts. It's always possible to derive the correct XPath expression of an alfresco content by using the 'Node Browser'.
After that, you can start testing. The bootstrap happens when you startup the first time after installing that AMP. There is no good way to uninstall AMP right now, so for testing purposes, you can delete your db and file store, and recreate it from scratch. There might be a better way, don't know.
Remember that your rm_categories.xml must contain only cm:generalclassifiable categories.
An example of the XML file is provided below:
<view:view xmlns:view='http://www.alfresco.org/view/repository/1.0'
xmlns:sys='http://www.alfresco.org/model/system/1.0'
xmlns:cm='http://www.alfresco.org/model/content/1.0'>
<cm:category>
<cm:name>Your Root Category</cm:name>
<cm:subcategories>
<cm:category>
<cm:name>Your Parent Category</cm:name>
<cm:subcategories>
<cm:category>
<cm:name>Your Child Category</cm:name>
</cm:category>
</cm:subcategories>
</cm:category>
</cm:subcategories>
</cm:category>
</view:view>
An alternative to the acp import is pointing to files explicitely via xml.
<bean id='customSpacesBootstrap' parent='spacesStoreImporter' singleton='true' >
<property name='useExistingStore'>
<value>${yourmodule.bootstrap.data}</value>
</property>
<property name='bootstrapViews'>
<list>
<props>
<prop key='path'>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}</prop>
<prop key='location'>alfresco/module/yourmodule/bootstrap/config_email_templates.xml</prop>
</props>
</list>
</property>
</bean>
In the snippet above, config_email_templates.xml contains the actual file references, as well as all file/folder properties. All predetermined files/folders will be placed in the 'Company Home/Data Dictionary/Email Templates' space.
Property Values
A good trick is to use a global property value for the 'useExistingStore' to turn bootstrapping on alfresco startup on or off.
If the store does not yet exist (the very first time a new alfresco installation starts up), the data will aways be bootstrapped, no matter the value, but from that moment on the store exists, and setting this to false means the next alfresco reboot these files won't be overridden with those on the classpath. Set it to true again and the next reboot the classpath files are loaded! Only import when YOU want it!
(!) XML imports can only replace/update/delete files that have their UUID set. (See #Import Strategy)
If you wish to bootstrap data to other stores or see all the available options, check out the import-export-context.xml
Back to the config_email_templates.xml, what would that look like?
<view:view xmlns:view='http://www.alfresco.org/view/repository/1.0'
xmlns:cm='http://www.alfresco.org/model/content/1.0' xmlns:app='http://www.alfresco.org/model/application/1.0'
xmlns:emailserver='http://www.alfresco.org/model/emailserver/1.0'>
<cm:folder view:childName='cm:My First Folder'>
<app:uifacets />
<cm:name>My First Folder</cm:name>
<app:icon>space-icon-default</app:icon>
<cm:title>My First Folder</cm:title>
<cm:description></cm:description>
<cm:contains>
<cm:content view:childName='cm:custom_email_template.ftl'>
<view:aspects>
<cm:titled />
<cm:author />
<app:inlineeditable />
</view:aspects>
<view:properties>
<app:editInline>true</app:editInline>
<cm:description>This is a custom email template.</cm:description>
<cm:content>contentUrl=classpath:alfresco/module/yourmodule/bootstrap/custom_email_template.ftl|mimetype=text/plain|size=|encoding=UTF-8|locale=en_US_</cm:content>
<cm:title>My first email template</cm:title>
<cm:author>Me</cm:author>
<cm:name>custom_email_template.ftl</cm:name>
</view:properties>
<view:associations></view:associations>
</cm:content>
</cm:contains>
</cm:folder>
</view:view>
In the snippet above, you see a folder is being added, containing a single freemarker template file. You can add multiple files/folders on the top level or in folders this way. You probably also noticed a couple of aspects that were set on the new folder, and their actual values. For more examples, check out the spaces.xml file. They're are several good examples to be found on the classpath already, see the /alfresco/bootstrap folder.
If you know the UUID(s) of the spaces/files you're importing, you can choose out of a number of import strategies.
<view:properties>
<sys:node-uuid>b7c6b88a-e5fd-4ccf-b134-69a2460c3b89</sys:node-uuid>
...
</view:properties>
</cm:content>
</cm:contains>
</cm:folder>
</view:view>
CREATE_NEW, CREATE_NEW_WITH_UUID, REMOVE_EXISTING, REPLACE_EXISTING, UPDATE_EXISTING, THROW_ON_COLLISION
(org.alfresco.service.cmr.view.ImporterBinding.UUID_BINDING)
See ACP#Import UUID Bindings for a more detailed explanation.
You can add these as follows:
<bean id='myModule.bootstrap'
class='org.alfresco.repo.module.ImporterModuleComponent'
parent='module.baseComponent'>
<property name='uuidBinding'>
<value>REPLACE_EXISTING</value>
</property>
...
<property name='bootstrapViews'>
<list>
<props>
<prop key='uuidBinding'>UPDATE_EXISTING</prop>
<prop key='path'>/${spaces.company_home.childname}/${spaces.dictionary.childname}</prop>
<prop key='location'>alfresco/module/yourmodule/bootstrap/myimport.acp</prop>
</props>
...
</list>
</property>
</bean>
The following are the substitution tokens that can be used for bootstrapping purposes. These tokens can be redefined in the configuration files if needed.