Email template changes in Alfresco - alfresco

I'm trying to edit the link of the task-edit of the e-mail that is sent to the assignees of the task. I see that in the file wf-emails.html.ftl but in Data Dictionary -> Email Templates -> Workflow Notification inside Alfresco admin account. How can I edit this file through a module of Alfresco (all-in-one for example, in the amp's)...
I put in the
module-context.xml
<bean id="customSpacesBootstrap" parent="spacesStoreImporter" singleton="true" >
<property name="useExistingStore">
<value>true</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/repo-amp/bootstrap/config_email_templates.xml</prop>
</props>
</list>
</property>
</bean>
config_email_templates.xml
<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/repo-amp/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>
And in the
custom_email_templates.ftl
I put the template with edits.
But the email doesn't edits.
How can I do this?

From Alfresco documentation :
XML imports can only replace/update/delete files that have their UUID set.
If you want to replace an existing node, you'll have to look more about import strategy :
<bean id="myModule.bootstrap" class="org.alfresco.repo.module.ImporterModuleComponent" parent="module.baseComponent">
<property name="uuidBinding">
<value>REPLACE_EXISTING</value>
</property>
...
Of course, you'll need to know the uuid of the file you want to replace :
<view:properties>
<sys:node-uuid>b7c6b88a-e5fd-4ccf-b134-69a2460c3b89</sys:node-uuid>
....

Here:
Alfresco Login Reset Repo AMP
https://github.com/teqnology/alfresco-login-reset-repo
you'll find the source code example of how to add a custom email template.
More specifically, the email template is located here in the file named:
alfresco-email-template-bootstrap.acp
In the end, here is the file service-context.xml which contains the info on how to import such bootstrap file of your custom acp (with your custom email template in it).
'
Hope this helps.
Cheers.
Long story short you should have this setup in your maven project:
Your email template packed as an acp (you can use the old Alfrecso Explorer interface to export your ftl templates): src/main/amp/config/alfresco/bootstrap/emailtemplate.acp
Your service-context.xml file declaring the bootstrap import of said acp file here: src/main/amp/config/alfresco/module/<yourmoduleid>/context/service-context.xml
From there you're free to use it through Alfresco JS API, eg:
var mailTemplates = search.xpathSearch("/app:company_home/app:dictionary/app:email_templates/cm:custom-email-template/cm:youremailtemplate.ftl");
if(mailTemplates.length > 0){
mail.parameters.template = mailTemplates[0];
}else{
mail.parameters.text = "Rollback to plain text if template is not found";
}

Related

How to create/define a sub resource via XML in API-Platform?

I am trying to create a sub resource via XML using Api Platform.
When I define the sub resource via a annotation on the entity, everything works as expected:
Entity/SocialProfile/SocialProfile.php
/**
* #ApiSubresource()
*
* #ORM\OneToMany(
* targetEntity="SoapSyliusSocialPlugin\Entity\Follow\Follow",
* mappedBy="follower",
* cascade={ "persist", "remove" }
* )
*/
protected $following;
Everything works as expected and I can then access the sub resource via the below path:
/api/v2/social-profiles/35471/followings
But when I try define this route/endpoint via .xml like the below:
Resources/config/api_resources/SocialProfile.xml
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<subresourceOperations>
<subresourceOperation name="api_social_profiles_followings_get_subresource">
<attribute name="method">GET</attribute>
</subresourceOperation>
</subresourceOperations>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" />
</property>
</resource>
</resources>
I am getting a:
404 No route found
I have tested my SocialProfile.xml file with a itemOperation & everything is working as expected.
I have updated my Resources/config/api_resources/SocialProfile.xml to look like the below, but I am still receiving a
404 route not found
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<itemOperations></itemOperations>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" collection="true"/>
</property>
</resource>
</resources>
The configuration for the entity holding the subresource (SocialProfile, in this example).
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" />
</property>
</resource>
</resources>
To configure things like normalization groups for the subresource, you do it in the other end of the relationship:
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\Follow\Follow" shortName="Follow">
<subresourceOperations>
<subresourceOperation name="api_social_profiles_followings_get_subresource">
<attribute name="method">GET</attribute>
</subresourceOperation>
</subresourceOperations>
</resource>
</resources>
Try with this. I have a few setup this way and working. If there is something wrong above should be because something does not match your class/resource names exactly, but you should be able to tweak that to fix it.
Note that in the second version of the configuration in your question you removed all itemOperations. You should have at least the basic get item operation so the library is able to build IRIs.

Create a new kind of site Alfresco 5.2

I'm trying to create a new type of site. When I'm creating a new one, only appears 1 type in the select: "Collaboration Site". I wish to add more options. For example "Custom Site", and for that site having predefined pages and dashboard. I've got a solution for this but it's modifying presets.xml and share-header.get.js files. I want to do the same by adding my own files, not editing existent files.
Thanks in advance.
You are correct to want to avoid touching out-of-the-box files that came with your Alfresco distribution. You can add new site presets through the standard extension mechanisms.
For example, you should be able to put a presets.xml file in web-extension/site-data/presets that describes your presets. It sounds like you already have an example of what that should look like.
Then, under web-extension/site-webscripts/org/alfresco/modules you can add create-site.get.js which has something like:
var sitePresets = [
{id: "site-dashboard", name: msg.get("title.collaborationSite")},
{id: "some-new-preset", name: msg.get("title.somePreset")}
];
model.sitePresets = sitePresets;
Note that this has changed slightly depending on which version of Alfresco you are using. For example, in 5.2, I don't believe you need to override create-site.get.js as shown above. Instead, you can use a Share extension module. Create a file called presets.xml in web-extension/site-data/extensions:
<extensions>
<modules>
<module>
<id>Additional Site Presets</id>
<version>1.0</version>
<auto-deploy>true</auto-deploy>
<evaluator type="default.extensibility.evaluator"/>
<customizations>
<customization>
<targetPackageRoot>org.alfresco</targetPackageRoot>
<sourcePackageRoot>com.someco.presets</sourcePackageRoot>
</customization>
<customization>
<targetPackageRoot>org.alfresco.share.pages</targetPackageRoot>
<sourcePackageRoot>com.someco.presets</sourcePackageRoot>
<alwaysApply>
<webscript>share-header</webscript>
</alwaysApply>
</customization>
</customizations>
</module>
</modules>
</extension>
With that extension in place you also have to override share-header.get.js. To do that, create a file with that name under web-extension/site-webscripts/com/someco/presets/share/header with this content:
var siteService = widgetUtils.findObject(model.jsonModel, "id", "SITE_SERVICE");
if (siteService && siteService.config)
{
siteService.config.additionalSitePresets = [
{ value: "some-site-preset", label: msg.get("title.someSite") }
];
}
This should add the new "some-site-preset" to the list you see when you create a new site in 5.2.

ZF2 how to disable Zend\Feed\Writer\Feed extensions

Trying to create a simple rss feed in zend framework2 by using Zend\Feed\Writer\Feed:
$feed = new \Zend\Feed\Writer\Feed();
...
$out = $feed->export('rss');
echo $out;
And this will output:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
<title>example</title>
<description>example</description>
<generator>Zend_Feed_Writer 2 (http://framework.zend.com)</generator>
<link>http://www.google.com</link>
<item>
<title>article1</title>
<pubDate>Fri, 11 Apr 2014 06:32:53 +0000</pubDate>
<slash:comments>0</slash:comments>
</item>
<item>
<title>article2</title>
<pubDate>Fri, 11 Apr 2014 06:32:53 +0000</pubDate>
<slash:comments>0</slash:comments>
</item>
</channel>
</rss>
My question is:
how to disable xmlns:slash extension <slash:comments>0</slash:comments>?
It's quite a mess in the Zend\Feed component with extensions. I have been messing around with it for a while.
What happens?
You construct a Zend\Feed\Writer\Feed. The Feed extends the Zend\Feed\Writer\AbstractFeed. In the __construct() of AbstractFeed happens this:
public function __construct()
{
Writer::registerCoreExtensions();
$this->_loadExtensions();
}
Writer is here the Zend\Feed\Writer\Writer. The registerCoreExtensions looks as follows:
public static function registerCoreExtensions()
{
static::registerExtension('DublinCore');
static::registerExtension('Content');
static::registerExtension('Atom');
static::registerExtension('Slash');
static::registerExtension('WellFormedWeb');
static::registerExtension('Threading');
static::registerExtension('ITunes');
}
Here, you see the different extens are added to the static Writer instance. From there on, the _loadExtensions() call fetches all extensions registered from the Writer and imports them into the Feed. The same happens by the way in the AbstractRenderer.
How to fix?
Because internally inside the Feed and Renderer the registerCoreExtensions() is called, you cannot overwrite the default list of extensions. Also, the Feed and the Renderer do not have getters/setters for the extension. The only way I came up with is to write your own Feed object and Renderer object.
For the Feed object you create a getter/setter to remove the extensions you want. You also override export where you copy the contents of the method, but overwrite the $renderClass variable name to the render class of your own.
For the Renderer class you create a getter/setter to remove the extensions you want as well. This way, you can tune the extensions you need. It's not that pretty, but hopefully it's something improved upon in ZF3 :)

Make default tab 'edit' for content type

Is there a way to make the default selected tab for a particular (developed) content type 'edit' when users are logged in?
you can use an approach similar to the one used in the Link content type.
assuming you are using Grok, create a browser view like this:
from five import grok
from plone import api
from my.contenttype.interfaces import IMyContentType
grok.templatedir('templates')
class MyContentTypeRedirectView(grok.View):
grok.context(IMyContentType)
grok.name('my_redirect_view')
grok.require('zope2.View')
def render(self):
"""Redirect to the target URL if the user is logged in."""
context = self.context
mtool = api.portal.get_tool('portal_membership')
is_anonymous = mtool.isAnonymousUser()
if is_anonymous:
return context.restrictedTraverse('##view')()
else:
return context.restrictedTraverse('##edit')()
in your content type FTI XML file set the following:
<property name="default_view">my_redirect_view</property>
<property name="default_view_fallback">False</property>
<property name="view_methods">
<element value="my_redirect_view" />
</property>
this way when the user is anonymous it will be redirected to the standard view and when it is logged in, it will be redirected to the edit view.
you can see code similar to this in the sc.banner custom content type.

Alfresco dynamic link in dashboard

I want a dynamic link to be generated and placed in a users' alfresco dashboard. The link would be say "inbox" which will have to be in the following format http://www.mysite.com/preauth.jsp?email=hello#domain.com . The only dynamic part of the link would be hello#domain.com which will be the email address of the user currently logged in. How can this be achieved Any help will be greatly appreciated.
Using alresco community 4.2a
If you'd like to implement this using a dashlet then take a look at will's sample dashlet on github: https://github.com/share-extras/sdk-sample-dashlet
All you need to do is to modify the ftl of the dashlet:
...normal html
link
Another approach is to add your link to Alfresco Share's header & add the following item (http://wiki.alfresco.com/wiki/Share_Header):
<item type="external-link" id="pre-auth">http://www.mysite.com/preauth.jsp?email={useremail}</item>
{useremail} is an unkown token here, thus you'll have to customize site-webscripts\org\alfresco\components\header\header.get.html.ftl & add your token there (sorry only 4.1 code as i don't have a 4.2 in-place):
<script type="text/javascript">//<![CDATA[
var ${jsid} = new Alfresco.component.Header("${jsid}").setOptions(
{
siteId: "${page.url.templateArgs.site!""}",
siteTitle: "${siteTitle?js_string}",
minSearchTermLength: ${args.minSearchTermLength!config.scoped["Search"]["search"].getChildValue("min-search-term-length")},
tokens:
{
site: "${page.url.templateArgs.site!""}",
pageid: "${page.url.templateArgs.pageid!""}",
userid: "${user.name?js_string}",
useremail: "${user.email?js_string}",
}
}).setMessages(${messages});
Alfresco.util.createTwister.collapsed = "${collapsedTwisters?js_string}";
//]]></script>

Resources