I am interested in triggering code to run when any changes are made to any documents or folders under a specific folder in alfresco. I am sure alfresco has to support this some how but I am not entirely sure what the feature/api/service is called or what to google for. What has this ability in alfresco and what is it called?
I am aware that its possible to create custom content rules in javascript and then add them to a folder to be triggered by some action. I did that a couple years back for auto filing documents that were dropped into a specific folder. Problem is that requires adding that action to each folder you want to monitor. I want to monitory an entire directory tree basically.
EDIT:
Correct me if I am wrong, but it appears that Events API may do what I need to do. I found this right after posting my question.
#Gragravarr answer is the best for handling events over a subtree of the repository.
In case what you need to monitor is only a subset of all the content of the subree (e.g. watch all the incoming documents, but only if they are PDF) and possibly scattered across the whole repository, then creating a specific content type and handle events using Policies is probably a better option.
You probably just want to create a Rule on the top folder, and set it to apply to subfolders. If you're interested in changes, then set a When of "Items are updated". Depending on your needs, you could also restrict it to only items of a given type or aspect (eg to pick up document changes, but not folder changes)
Finally, you can either have your Rule run a JavaScript file (Execute script) to perform the business logic, or you can register a Java Custom Action and have that triggered
Related
Am new to Alfresco, so this might be trivial, but I couldn't find the answer....
While using Alfresco Share, I will have many sites to be created. These are not known beforehand and will be done one at a time via the UI. I would like to have a standard set of 3 folders created each time I create a site. I think rules can be used for such a purpose?
Is this possible? If so, could you outline the detailed steps necessary? (New to Alfresco!)
thanks
Yes, a rule should be the starting point for this. The rule needs to be created on the Sites folder and set to "run on subfolders".
When your rule fires, it will be handed the folder that represents the site.
Sites have "containers" for the various tools used in the site which are just folders that site in the site's root folder. The container folders have a specific aspect and a component ID. Those containers get created lazily--they don't get created until the first user uses the component.
In your case, that means when you create a site, it doesn't contain a Document Library folder (it's actually named "documentLibrary") until someone uses the document library for the first time.
That means your rule will have to create the documentLibrary folder in the site folder. It needs to be named exactly like that, it needs to have the "st:siteContainer" aspect, and it needs to have st:componentId set to "documentLibrary".
Once that's done, your rule can create the standard set of folders, then you are done.
Because there is no out-of-the-box action that does what I've described, you'll use server-side JavaScript to implement this rule which just means you'll write the rule in JavaScript, upload it to Data Dictionary/Scripts, then point to it when you configure your rule.
As a side note, if your standard set of folders will change frequently, is complex, or needs to include documents (like sample content or something), you might want to use a space template and then create the documentLibrary folder based on that space template. If that sounds like overkill or isn't what you need, then forget I mentioned it and just have your rule create the three folders.
So I'm working on a project with pretty specific client requirements. The want a document that, once uploaded, is automatically given a custom content model (which I've already made) and then, immediately after upload, allow the user to select aspects to add to it. If the user cancels out of the aspect selection, the document needs to be deleted.
We have a full Maven space setup for alfresco and share development and have our standard-document.xml in alfresco/src/main/resource/alfrescco/extension/model.
The question I have is, where in my share environment do I start working on this process? Would it be best to make a custom dashlet that deals with the upload process, or is there some class or function I can rewire within the Slingshot/Spring Application Context. I couldn't find any existing plugins or share amp files that I could use as a reference. Is there anything out there that currently has something similar to this functionality?
I guess you're using Alfresco's Share client, right?
you'll have to have to tweak Share's JavaScript components:
add a custom flag to "metadataRefresh" event object that is fired in x-upload.js
tweak handling of "metadataRefresh" event in documentlist.js to call the relevant action
it's gonna be a though JavaScript implementation task.
I'm very new to Alfresco. My question is, how can we use a dashlet (created from scratch) into a page (created from scratch too)? What are the files and configurations to deal with, for including a dashlet into a page.
Moreover, the newly created page has to be similar to dashboard page but without authentication. The idea here is to do away from the default "Share" dashboard login flow.
Thanks.
A dashlet is simply a special type of web script, so yes, it is quite possible to place the same web script into a custom page by binding it into a component region.
The relationship between pages, templates, components and regions can be a little complex if you're new to Share development, so I'd recommend reviewing Dave Draper and Erik Winlof's Share Customizations Live presentation from last November's DevCon, where they introduce a sample project including an Ant build script and which includes a custom web script and page definition. The code can be downloaded from this Git repo as a basis for your own project.
You should not find that too many changes if any are required to your dashlet web script to make it work inside a custom page, but remember that if the user is unauthenticated then you will not have access to any information about them, nor will you be able to retrieve any data from the repository.
Let me try to answer this with some examples:
Alfresco page
To create an Alfresco Share page (you use share?), you need to create three files:
<TOMCAT>/webapps/share/WEB-INF/classes/alfresco/site-data/pages/my-page.xml
<TOMCAT>/webapps/share/WEB-INF/classes/alfresco/site-data/template-instances/my-page.xml
<TOMCAT>/webapps/share/WEB-INF/classes/alfresco/templates/org/alfresco/my-page.ftl
The first one defines your page, the second one defines what components (dashlets) you will use on the page, and the last one is a HTML template (in Freemarker) arranging your components.
The first two files are XML, a bit alfresco specific, but simple XML, and the last one you could put static HTML and it'd work, or you could put some freemarker macros.
What is in each of those files (examples), you can read on this page, written specially for you and this question :) (Don't ask, I felt like writing about it)
No authentication
To not use authentication, you can just put <authentication>none</authentication> in the page definition file (the first XML file).
Dashlet files
Basically, a dashlet can be at the minimum two files, usually 4-5 or something like that. The dashlet.get.desc.xml file signifies two things: desc.xml part says it's for a new component (dashlet), and get part says this component will answer to HTTP GET calls.
is usually placed somewhere bellow /webapps/share/WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components. Doesn't really matter where bellow, but you would want to put it in some folder to manage all your code easier.
This file contains one important thing: url. Url defines what url your dashlet will answer to. And when you defined your page in the page definition above, you would put this url there to access the dashlet.
You could even access the dashlet directly, using the link http://localhost:8080/share/my/url/to/dashlet.
The other file, dashlet.get.html.ftl is, again, a freemarker template file. You put HTML there. You can also have a controller file for the dashlet, dashlet.get.js which prepares some dynamic content (it is written in server-side javascript and has access to some of Alfresco Javascript API).
Finally, you can put some internationalized text (translations) into bundles (basically, dashlet.get.properties, dashlet.get_DE.properties, dashlet.get_ES.properties etc, by browser lanugages).
There are also options to include client-side javascript or css files to this dashlet.
To see how exactly to assemble all this, you could try reading this page. Probably not really a good read, but it will hopefully clear some things up.
Sorry, just to be clear, you want to reproduce a share interface on an Alfresco repository, but without the login? Dashlets and interface components are webscripts, and webscripts are stored inside the repository, so in order to access them you need to be authenticated. You could use tag in the webscript xml description a runas="admin" or runas="guest" in order to achieve something. If i misunderstood, please let me know, and I'll try to help..
I'm mucking around with the new ASP.NET bundling features (using the System.Web.Optmization 1.0.0-beta pre-release) in my ASP.NET MVC 3 web application.
Works great.
However, we have certain dynamic CSS/JS which is stored in the database.
I want to get this added to a seperate bundle for my core bundle, say "DynamicBundle". I know how to do that, not a problem.
Now my question is, when this CSS/JS is changed in the database, that bundle needs to be "refreshed" so that the content of those files are re-read in to the bundle.
Essentially, i need ASP.NET to re-generate that magic guid/string that is appended to the bundle URL.
Ideally, i'd only like to refresh a specific bundle, not the entire bundle table.
Is there a way to do this?
EDIT:
Okay second problem, can't figure out how to add the dynamic CSS/JS to the bundle. bundle.AddFile takes a virtual path to a file, but it's not a physical file, it's a string. How am i going to do this? Surely i don't have to write out string to files first?
EDIT 2:
So i've decided not to bundle my dynamic content. For 2 reasons:
It's only 1 file, so i'm not gaining any "bundling" benefits
Bundling is designed for static content, this is not
So what i've done is manually minified my dynamic css/js at runtime (once, then cached). That way i can easily refresh it, by simply clearing the cache.
That being said, this is still a relevant question (refreshing bundles) so i'll leave it open..
That "that magic guid/string" is a hash of the combined file contents.
You can test this with the following workflow which assumes that you have a mybundle.css. If you use Fiddler to watch the traffic, you will see it request something with a hash like
http://localhost:20206/mybundle.css?v=-6520265193368900210
Now, "touch" one of the files in the bundle as much as you want without actually changing the contents. The file is newer (LastModified / LastWrite is more recent), but the hash remains constant as it is being computed from the same combined contents. You could even add spaces to the file since those would be minified out.
http://localhost:20206/mybundle.css?v=-6520265193368900210
Next, actually make a change. Perhaps set a border to 2px instead of 1px. The hash will change now, since the contents feeding the hash have changed.
http://localhost:20206/mybundle.css?v=-4725541136976015445
Finally, set the border back to what it was (in the above example, back to 1px). The "magic string" is actually not random or magic at all. Instead, it returns to the matching one-way hash computed from the contents.
http://localhost:20206/mybundle.css?v=-6520265193368900210
Now you can rest easy that the hash will update only when it is needed, without manual intervention.
As for the other part of your question,
when this CSS/JS is changed in the database, that bundle needs to be
"refreshed" so that the content of those files are re-read in to the
bundle.
I think we just reverse the thinking. Instead of refreshing the bundle to trigger a re-read, we update the files to trigger the refresh. When ASP.NET sees the file(s) change, it will recombine the contents and update the hash.
I have good news for you. Many people have been asking for virtual path provider support for scenarios similar to yours, where they have content that's not necessarily from disk, so we currently are planning on supporting VPP in the next release.
To take advantage of this support, you will have to implement a VPP for your dynamic js/css.
VPP also has cache dependency mechanisms built in, so we should be able to use those to automatically flush the correct bundle cache entry for you.
Is there any way to show local tasks to user if they doesn't have necessary permissions? Right now it seems like Drupal just excludes them from page code. I want to show them, but with different CSS class.
Version of Drupal is 5.20
Even though there are some differences concerning the local task building between Drupal 5 and 6, Mac is right that the logic to ignore entries not accessible by the current user is pretty deeply embedded in the menu.inc functions. If you want to look for yourself, start with theme_menu_local_tasks() and follow the function calls from there.
If I had to implement the feature you're looking for, I'd rather avoid Macs suggestion of messing around with the menu access settings directly. Instead, I'd override theme_menu_local_tasks() with a custom version and duplicate the entry retrieval logic in there. The first run would fetch the primary and secondary links as before, and the second would do the same while impersonating another user (probably user 1 in this case). That way, I'd get two versions of the local task markup which I'd then needed to diff somehow in order to find the ones not allowed for the current user, thus needing the extra CSS class.
Note that this would still be somewhat ugly to do, as menu_primary_local_tasks() and menu_secondary_local_tasks() return already themed lists, so the comparison would need to work on the markup, probably parsing out the li tags somehow. So it might be worth spending some time trying to do the same thing (fetching the local tasks as two different users), but using lower level functions to get the entries before theming.
Note: Should you end up using the user impersonation logic, make sure to use the safe, second version that disables session saving during impersonation.
I know the D6 version of hook_menu much better than D5's. AFAIK - however - you can't override that behaviour as it is hardcoded in menu.inc.
If I am right with what above, a workaround (rather inelegant, I must admit) could be:
Remove the access control from the menu item, so that all menu items are visible to all user.
Put access control in the callback directly (you will make the tab non-clickable in a moment, but if the user insert the URL directly, this will prevent access to pages they must not see).
In the page displaying the tabs, load a different js file according to what roles the user has. The js file for users with limited access will select tabs by mean of their text content (at least in D6 tabs do not get any "individual" class: they only get a common "tab" one), it will remove the link to the tabs the user has no permission to visit and it will add a custom class to those tabs that should be displayed differently.
Add CSS theming for your custom class.
As stated before, I do not know D5 much, so it might also turn out that you can actually achieve what you want in a much cleaner way!