How to create several folders in Alfresco Share when creating a Site? - alfresco

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.

Related

Convert query parameters to "pretty urls"

I have an Episerver site with a JobDetailsPageController with a Index method that takes a jobId parameter and creates a view with some details about that job. The urls looks something like this: https://hostname/<root-depending-on-site-tree>/jobs/?jobid=44.
What I would like is having urls on the form .../jobs/manager-position-telco-44, essentiallly creating a slug of the job title and appending the id. I have done this in the past using standard ASP.NET MVC Attribute Routing on a non-Episerver site, but EpiServer has a routing of its own that I don't know too well and can't figure out.
Also, adding non-query strings after the slash consistently sends me (no surprise) to a 404 page, so I would need to somehow customise this behaviour. I need to use EpiServers standard routing to end up at the right "parent", but ignore the latter part (the pretty bit).
Is it possible to create such urls on a normal page in page tree in EpiServer? I do understand it is possible to create static routes, but this node can be moved around like any other page so I cannot avoid EpiServer.
Please see this blog post. What you're looking for is partial routing.
#johan is right, partial routing is one way of doing this. Just wanted to add other possible solutions that might or might not match your needs.
Import data as content
Instead of serving content dynamically, you could consider importing your job ads from whatever source you have directly in content tree as separate pages below particular root page. That would give you a lot benefits - pages would be cached, it would support multiple languages, editors would see content directly in EPiServer CMS, data could be adjusted manually, etc.
This would be a good solution if your data does not change often and you need to provide a way for editor to create a new job ad manually as well.
Implement you own content provider
Another way to serve your dynamic data to EPiServer is to write your own custom content provider. You can find documentation here: http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-CMS/7/Content-Providers/Content-Providers/
This solution requires more coding and is more complex, but it has some benefits as well. If one wanted, it would be possible to not just serve content from external data source, but also update that data by changing values directly in EPiServer UI.

Alfresco Share | Using dashlet into a custom page programmatically

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..

New ASP.NET Bundling Features - How can i programmatically refresh a certain bundle?

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.

Does Alfresco support monitoring entire folder tree for changes?

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

What is the best way of duplicating an entire website?

I've built a complex site for a client, who wants this duplicated, and re-skinned, so it can be used for other means.
What is the best way of doing this? I'm concerned about copying every file as this means any bugs must be fixed twice, and any improvements must be implmented twice.
I'd look to refactor your code.
Move common functions into a library you can reference from both projects. As you mention that the new site is for a different purpose then you are likely to see divergence and you don't want to hamper yourself later, so extract the common parts and then modify copies (or if appropriate new files) of the remainder to complete your fork.
If you haven't applied good practice already then now is the time to do it and it'll make your work on both sites easier moving forward.
If all the functionality is the same and only the layout is different you could just create a new css file. 2 websites could have exactly the same code base but have different stylesheets and look completely different.
I think that using a version control system like subversion or preferably git, is a good way to duplicate your website. You will be able to track the changes that you make and revert to older versions if things do not work out.
You should implement some kind of instantiation, so look and feel, content and data will be shown depending of what instance of the application is accessed.
In other words, each application access to the code with a different application identifier, meaning content will be served depending on it.
Both application identifier will be pointing to different settings, so stylesheet and content will be absolutely isolated, and both domain will be living in the same IIS application.
If you want to duplicate a whole site it's probably best to copy the whole thing and amend as necessary. Obviously taking great care not to copy large portions of text or else you may be penalised by the search engines.
There are ways you could put the new site onto the same shared host (say within a subdirectory of the original site) and literally 'share' some files. If a unique change is required, you could instead reference a 'local' version of a particular file.
However that sounds like a recipe for a headache to me. I'd prefer to duplicate the whole site. It would be much easier to replace one or two functions on separate websites than it would to try and work out which website(s) are affected by a particular change to your source.

Resources