|
|
|
OpenCms is a powerful open-source content-management system. But if you're reading this, you already know that. OpenCms is also relatively complicated, hard to learn, and severely lacking in tutorials and beginner level documentation. If you're reading this, you probably also already know that. My frustrations with all the documentation (or lack thereof), and the amount of unanswered entry-level questions in the forums and official mailing list, led to this document.
The other difficult part is that all the documentation I could find was about OpenCms 5.0. Which is different enough to cause problems. I entered some example code from an OpenCms 5.0 tutorial, tried to view the resulting page, and all that displayed was an error message saying "Null." Great, at least we know that OpenCms has descriptive error messages that will help you diagnose potential problems. Or not. So, after suffering through figuring it out, I thought there was a need for me to record what I've learned. I am no expert of this system, so there's a lot I still don't know, and some of this may even be wrong. I just want to share what I picked up to make it easier for you.
First, why use OpenCms, or why not? This was already a hard question to find the answer to. Beneath all the propaganda and marketing speak (you'd think an open-source project would have less of that? I guess I was wrong), it was hard to find a clear summary of what OpenCms is good at, and what it isn't.
So, here's a quick summary:
OpenCms excels at (and seems to be geared towards) usage in something like an organization's website, where there are many pages of relatively static text. It provides a way for non-programmers to easily update the text and structured content (downloads, lists of links, etc).
OpenCms is not a blog/forum/discussion board-style cms system. Although you can customize it or install additional modules to get some functionality of that type, there are other software packages that are made to do those things, and do them easier and better. If you want your end-users (as opposed to specific editors) to regularly add content, consider using a different package.
OpenCms is also very powerful when it comes to allowing complicated templating systems. This comes at the price of making these templates tricky to set up. While the apache lenya project will easily generate nav items for you, OpenCms makes you churn out a bunch of Jsp code to get a dynamic nav menu. But in the end, you can make some pretty powerful templates that give your site owners a lot of flexibility.
Another thing about OpenCms that is both an advantage and disadvantage is the fact that all configuration and Jsp writing is done through a web interface. This is good because you can easily administer a site remotely. This is bad because most of us gave up notepad for editing long ago. Going back to editing code in an html textarea is really quite a nightmare.
Ok, after all that, if you still want to go on and use OpenCms, you first have to get it installed. So, let's dive in.
This is the easy part. Why? Because there's already a lot of documentation about it.
So I'm not going to say a lot about it. (And because if you are frustrated enough to search and find this document, you probably have installed it, logged in, and stared at the screen thinking "what now?")
Basically, make sure you have the prerequisite stuff on your machine (Java SDK, a servlet container, and a database). If you plan to use other things besides Tomcat and MySql, then you are in for a fun journey. If you just use the default stuff, it's not too hard.
Download the OpenCms war file, drop it in your tomcat webapps directory, and let it do its stuff.
Easy, right?
Except for when you try to log in and get some crazy error message about file encodings. I think this is sort of like the weed-out classes in college. The OpenCms developers decided to use a file encoding that is different from Tomcat's default. I can only guess they did this so that people who weren't clever enough to figure this out wouldn't bother them with any more questions about the rest of the system.
Anyway, the solution is to pass a file encoding parameter to your JVM:
-Dfile.encoding=ISO-8859-1
You can put this in your CATALINA_OPTS environment variable, or pass it on the command line that is starting tomcat.
Ok, carrying on, to get everything rolling, go to:
http://yourserver:8080/(servletname)/setup
(where servletname is the name of the webapp directory created in Tomcat, probably just "opencms")
Follow through the installation screens to get started.
At some point, you can choose which modules you want to install. I recommend installing them all, as the documentation will come in handy, and I find it much easier to make a copy of the templateOne example content and edit it, instead of building new templates from scratch. (You can always go back and delete the example directories later for a production environment).
It'll take a little while, but when it finally finishes, you should be able to get to a welcome screen with a login prompt. Login, and it should open up the "workplace."
Hooray! You got it installed. Give yourself a pat on the back.
Ok, before we dive in to making a site, let's go over some of the key things about OpenCms that the documentation doesn't like to bother explaining.

First, there's some stuff in the top bar to explain.
Project – this distinguishes between 2 things, the "Online" project and the "Offline" project. Basically, the "Online" project is the live version of your site, and "Offline" is the working version that only people logged in see. (why do they call these projects?). For the most part, you'll work in the "offline" project, because you can't do much with the "Online" project other than push your changes from offline to online. (this is called publishing). To make it even more confusing, it's possible to add new "projects" to the system. But any new projects you add are (I think) just subsets of the "offline" project.
Publish Project – this button will publish everything from offline to online
Site – In a normal configuration, the web root for your site is located at /sites/default in the cms's fake filesystem (the VFS). At the root of the VFS* are some of the cms's system files and such. So you can use this bar to jump between your website's content files, and the system files.
View – The main view is called "Explorer", which the windows explorer-style interface to the VFS. You can also select Administration, which lets you do system level administration. There are also some other options for workflow and legacy administration, but I won't talk much about those.
Then, below, you have the main explorer windows. Here, everything happens with a left-click. To view a file, click on it in the main window. To do any operations on a file or directory (edit, set properties for, lock, etc), left click on its icon, which will open a popup menu of options. It's a little counter-intuitive if you are used to right-clicking, but pretty simple overall.
*The VFS is the Virtual File System that OpenCms uses. Although it looks like a normal disk-based file system, all these files and directories are actually just entries in your database. VFS just refers to this "fake" file system.
One thing that was frustrating about learning to use OpenCms was all these terms. One tutorial I read led you through creating a new project for your new site. Then a new module. Great, I thought, now I can create a module. But what is a module?
Honestly, I'm still not sure I completely understand the details, but here's a basic description:
Projects – Like I said above, is either Online, Offline, or some subset of Offline. Basically, as far as I can tell, these are a way to organize folders in the VFS that you use for different purposes. For a website, you might define a project containing all the relevant directories from the VFS. Then, if you choose that project, you will see just those folders and files.
Modules – A module is package of files spread out all over the VFS for a specific purpose. For example, one module might be a website. Or a module might be a chunk of code and pages to implement a standard functionality such as a message board. Modules can be exported and imported into OpenCms as a group. Generally, you will probably want to create a new module for each website you are working on.
Sites – What it sounds like….a site that you can access from a web browser. /sites/default is the default place in VFS where your main site would lie.
Now something that confused me was where OpenCms keeps its files. All of your templates, site configuration, etc goes in the special /system folder, not with your site code. Specifically, when setting up a site, you will often use /system/modules/yourmodule, as that is where all the templates, resources, etc for the site will be kept.
An easy way to think about it is that the site folder's content should be the "content" that you want your editors to be able to manage: text, structured data, etc. The /system/modules/module folder should be the stuff that you, the template designer and coder, will mess with.
One thing that distinguishes OpenCms from some other simpler cms systems is the way it can use properties and structured content. Before we dive into how to create sites, it is nice to go over this, as it can really make a difference in how you design your site code and templates.
Each file and directory has a list of associated properties. These are mapped key->value String pairs. There are a number of standard ones, such as Title (the text-friendly title for a page, as opposed to the filename), the name of the template that the page should use for rendering, and some navigation properties (which let you determine how it is used in dynamic navigation menus). But then you also have a lot of flexibility in defining other properties that your editors can use.
For example, you might want some pages to cause the general template to display one way, and others to use a very slightly different way. A naïve implementation might be to copy the template, make a very minor change in the other version, and then in each page, specify which template to use. Doing it this way violates the DRY principal (Don't Repeat Yourself, see the Pragmatic Programmer series of books), so a better way might be to define a property that the person who is the page editor can change for each file. Your template, then, can read that property, and behave slightly differently depending on the value they set.
We'll get to how to deal with properties later. They can add complexity to coding your templates, so it won't be a walk in the park, but it will let you do some cool things to make life easier for you and your editors.
OpenCms also gives you the ability to define what it calls "structured content", which is really a fancy way of saying data in XML files. The nice thing about it is that it can generate nice user-friendly editing pages for your non-technical editors to edit the xml files.
For example, in the footer of a page, you may want a series of links such as Home, Contact Us, Site Map, etc. Instead of hard coding these in your template, or making your editor manage them as textual content, a nice way of dealing with it is to use structured content. You can then give your editor a user-friendly form for adding links, and your template will take care of transforming the XML data into nicely formatted xml.

In the screen shot above, the editing user can click the little red box by the list of links, and be presented with a nice gui for editing the links, below:

Of course, with both the properties and structured content, it can make things a little more complicated for you, the template designer. So for some small simple projects, it might be easier to ignore this. But it really does allow for more powerful editing by your content people, which can make a difference down the road, when you aren't getting called back over and over to make slight modifications to your template.
Ok, now it's time to dive into how OpenCms handles the templates for your site. Now I've been throwing around the word template assuming you know what I mean, but in case anyone is confused, when you build a site with OpenCms, there are basically 2 major parts: the template code and the content. The template is the code that builds the basic html framework that all pages use: the headers, nav, menus, etc. The content is the data that differs on each page: textual paragraphs, etc.
The "standard" way of using OpenCms would be to have you, the programmer, design the template code for a site, then let your less technical editors go in and make content-only changes. So while designing the templates is pretty heavy technical stuff, the goal will be that the editors can make changes REALLY easily.
One nice feature that OpenCms 6.0 added (I say nice, but without it, I think the technical level required for the editors is WAY too high), is that when previewing a page when logged in, OpenCms can put little "edit me" links (the red OpenCms logo box that you saw in the previous screenshots) on editable content blocks. The editors can then just click them to open the appropriate editor for the correct file. This way, they don't need to know where each content file is kept in the file system. As long as they can get to the index page of the application, they can navigate through the web page like normal, and then use the "edit me" links to edit what they want.
Ok, back to business. So let's go through how OpenCms does templates.
As I go through these descriptions, it can be helpful to have an existing template and website to refer to. I recommend making a copy of the templateOne demo and hacking away at it to learn.
Inside each module's directory, there should be a directory called /templates. (You may have to create it yourself. Another "newbie-friendly" feature of OpenCms is how they don't give you very many hints as to the names of some of these magical directories. You just have to know.) The system will look in these directories for a list of all available templates.

Now, each content page in back in the content area (remember, the content is often in /sites/default), will have an associated template. This way, for each page of content, you can choose which template type you will use to display it (for example, a site may have a basic display style, and a separate page layout for news items. You might build a different template for each layout, and then in the content section, choose whether the content will use the normal layout or the news layout)

Basically, an OpenCms request happens sort of like this (this is simplified though).
The user asks for /yoursite/opencms/About_Us/index.html
OpenCms will go find /sites/default/About_Us/index.html, load up the content from this page, look and see what template it is using, then call the template. The template then takes charge, displaying the entire page layout, and inserting the content in the appropriate place.
Now, even though in many examples, content pages are labeled as .html files, that can be quite confusing, because they really aren't. They are actually XML files with one or more content sections.
To see the actual xml code, you can select "Edit controlcode" from the file's menu. This is handy for understanding what is really going on in a page file:
<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.opencms.org/dtd/6.0/xmlpage.xsd">
<page language="en">
<element name="sidebar1">
<links/>
<content><![CDATA[this is the sidebar1]]></content>
</element>
<element name="sidebar2">
<content><![CDATA[content for sidebar 2]]></content>
</element>
<element name="sidebar3">
<links/>
<content><![CDATA[<table><tr><td>more sidebar content!</td></tr></table>]]></content>
</element>
</page>
<page language="de">
<element name="sidebar1">
<links/>
<content><![CDATA[dieses ist das sidebar!]]></content>
</element>
<element name="sidebar2">
<content><![CDATA[dieses ist das sidebar 2!]]></content>
</element>
<element name="sidebar3">
<links/>
<content><![CDATA[<table><tr><td>sidebar 3! </td></tr>
</table>]]></content>
</element>
</page>
</pages>
This is for a sidebar section I used in a site I was designing. This sidebar always had 3 different content elements. I considered using a different page for each element, but instead, decided on using 1 page for the entire sidebar, but have that page include 3 different content sections ("elements"). The template can then access each of these elements by name, and put them in the correct places in the layout.
Another thing to notice in the XML file is that the page contains content for multiple languages. We'll get into internationalization later, but the general idea is that the page itself contains all the different translations, and then you can use the "locale" property of the page to indicate which language you want to display at the time.
Ok, well, that's great and all, but you may wonder how your friendly editors can handle these multiple content blocks? When you select "Edit Page" from the context menu, you only see one block of content. Where are the others? They're there…you just need to select them from the menu at the top. You can select between content elements, and the language that you want to edit.

The tricky part is that pages by default won't necessarily have the correct content elements. That's again where the "edit me" links are handy. If you use them to open the content editor, it will open the file to the correct element, and create it if it doesn't exist.
Now, let's move on to the template files. This is a part that can be really confusing if you had the misfortune to read any documentation from earlier versions of OpenCms. (Including the book "Building Websites with OpenCms"). In previous versions of the software, templates were some sort of XML files that would combine your html and page content in all sorts of mysterious ways. You also had the option to call Jsp code also.
But now, it no longer works that way. Actually, it's fairly simple now, but I had spent so much time reading through documents trying to understand the old way, that I had gotten myself horribly confused.
Basically, templates are just JSP's. You write JSP and HTML code that will create the layout you want, then use a few custom tags or function calls to insert the proper content. It's that easy.
Conceptually, it's something like this (I'm simplifying the html code and breaking all sorts of web standards for the sake of simplicity and readability (and who am I to talk about web standards....this page you are reading was converted to html using the Word html exporter crap)
<%@ taglib prefix="cms" uri="http://www.opencms.org/taglib/cms" %>
<html>
<head>
<cms:editable />
</head>
<body>
<table>
<tr>
<td width='15%'>Static nav stuff!</td>
<td width='70%'>
<% //Include main page content here! %>
<cms:include element="body" editable="true"/>
</td>
<td width='15%'>
<% //Include sidebar content here! %>
<cms:include element="side" editable="true"/>
</td>
</tr>
</table>
</body>
</html>
This is just a simple example to illustrate the point. The JSP template takes care of building the page layout, and then uses Jsp functions or tags to include content page elements. In this case, it will include the elements "body" and "side" from whatever content page is using this template.
So, to see this template in action, you can create a Jsp file in your /system/modules/(yourmodule)/templates directory, and add this code.
Then, in your site directory, create a content page called Test.html, and give it content for these 2 elements ("body" and "side"). Edit the properties for the page and select your new template. Then click the name of the file and voila, it should fill in the 2 content includes with the page content. (See picture below. In the picture, I have moused over the "edit me" box on the right, which is why that section is highlighted.)

The cms:include tag lets you include content from any page. By default, it will be from the page file that is being displayed. But you can also specify file="xxx" and include content from other pages. This is handy if you want the layout to always include the same footer for each page, but you still want this page to be user-editable. You could create an html page called "footer.html" which would generally not be displayed directly, but only included from the template Jsp:
<tr>
<td>
<cms:include file="/footer.html" element="body" editable="true"/>
</td>
</tr>
Another interesting way of doing it is to have the file to be included be specified in a property of the original page file. That way, your friendly non-techy editor can easily determine which footer page will be included with each real page. The way to do this is to use the "property" attribute instead of the "file" attribute.
<tr>
<td>
<cms:include property="footerFile"
element="body" editable="true"/>
</td>
</tr>
Then, in this case, the editor can define a "footerFile" property for the page file, and indicate here which file should be included in this place.

(To define a new custom property, click the file icon, select Properties, then Advanced, then click Define. Type the name of the property you want to define, then hit Ok. This new property will then appear in the advanced property list for the file)

Now, let's back up and talk about those tags that say "editable." There's one in the page header, and in each include we also set editable to true. These just tell OpenCms to work it's magic and give us the little "edit me" links. (The technical word for these is "direct editable elements". But I like "edit me" better.) I generally turn these on, unless the html that OpenCms generates ends up messing up the page layout. In those cases, our poor editors will just have to use the explorer to hunt down the file themselves.
Now this in itself is enough to design a basic CMS system for your users. Sure, some things like automatic nav menus are missing, but it's enough to start with.
Now, you may still be wondering how to do fancier things (like those nav menus I was talking about, or to provide different actions based on file properties).
Well, the short version is: it's a Jsp -- just write code to do it. Plus, the cms TagLib reference will come in handy soon.
But, you probably want a little more detail than that. Of course you do, or else you'd be writing code right now instead of still reading this thing.
First, I recommend you take a look at the template system set up for the TemplateOne demo that comes with OpenCms. It's a bit extreme, in my opinion. It seems like they may have slightly over-engineered everything. But, the nice thing about that is that it gives you an example of how to do all sorts of thing.
For example, in the modules directory, you can see how there is a directory called "elements" that includes a lot of the different pieces that make up the layout – menus, nav blocks, titles, etc. Then if you take a look inside their main template file, you can see how they made "include" calls to those elements. This is pretty much your standard programming technique of breaking things into modular pieces to make it all easier to maintain. I highly recommend it.
Another interesting thing about the TemplateOne demo is how they actually wrote a few Java classes to encapsulate a lot of the code, so they could keep the Jsp's cleaner. While this is a good idea if your code base is pretty big for the project, it's not necessary for smaller templates. BUT, you might want to be able to steal some of the code they used in their java classes. No problem…just make sure you get a copy of the source for the TemplateOne demo, and anything you want to try to duplicate, read through the source and see how they did it. Later, you'll want to figure out how to add classes to your own modules (I won't cover that), but until then, remember that you can put code into your Jsp template as needed (even though it's ugly and violates all sorts of good coding principles). If you want to do things that aren't covered here, just dig in the examples and try to figure out how it was done, then plug that code into your templates.
But now, let's look at a few specific things you might want to do with your templates:
Sometimes you want to display a page property in the layout. For example, you will often want to put the page's title in the html title (which will usually appear in the browser's window title). This is an easy one….they give you a tag in the standard tag library to do it:
<cms:property name="Title"/>
For a page where Title is set to "My Page", this will render as My Page. Easy enough.
There are also some options you can add to set which file the property comes from. By default, it will come from the current page, but you can use the file attribute to choose a different file. Refer to the taglib section of the Alkacon documentation for more details. (Yes, I said their documentation wasn't great, but the reference section isn't bad once you know what you are looking for)
What if you want to get the URL of the page the visitor is currently requesting? One way would be to again use the taglib. You can use
<cms:info property="uri" />
The cms info tag will show you various run time information about where you are. Again, check the documentation for more. It's actually useful at this point.
BUT, what if you want to use this uri for something other than inserting it into html? For example, you might want to have your Jsp do some processing on this string value? Well, then we need to use some real code, and not just the taglib.
If you do everything by the book, you can dig through the javadocs and figure out that you want to create a new CmsJspActionElement and call getRequestContext on it. But what I find easier than digging through the docs for each thing I want to do, is again, just look and see how the TemplateOne handles it. It's pretty easy to find in their code an example, and you can see that they have extended the CmsJspActionElement into a CmsTemplateNavigation object, which they use in their code. Why not reuse their object?
So to get the uri, I just stole some code from their template:
<%@page buffer="none" session="false"
import="org.opencms.file.*,
org.opencms.jsp.*,
java.util.*,
org.opencms.frontend.templateone.*" %>
<%
CmsTemplateNavigation cms = new CmsTemplateNavigation(pageContext,
request, response);
String uri = cms.getRequestContext().getUri();
String title = cms.property("Title");
While we were at it, I also added the code for programmatically getting page properties, in case you want to do any processing against it as well.
Let's say you have a link at the bottom of the page that will let the website visitor see a printable version of the page. This printable version will be a whole different layout than the standard template. There are all sorts of crazy options, but again, looking at the TemplateOne code, you can find a nice way to do branches in your template Jsp based on pulling the request variables out of the getRequest method.
boolean isPrint = Boolean.valueOf(cms.getRequest().
getParameter("Print")).booleanValue();
if (isPrint){
%>
<!-- print version - skip navigation and right sidebar -->
<cms:include element="body" editable="true"/>
<%
}
else
{
<%
<!-- standard version -->
<table>
<tr>
<td width='15%'>Static nav stuff!</td>
<td width='70%'>
<% //Include main page content here! %>
<cms:include element="body" editable="true"/>
</td>
<td width='15%'>
<% //Include sidebar content here! %>
<cms:include element="side" editable="true"/>
</td>
</tr>
</table>
%>
}
Again, if you are building an entire clean template system, it will be better to build your own objects for reusable code instead of just lifting functionality from the example. But for the sake of learning, this will help you see things you can do with OpenCms.
Another thing you
might want to do is have certain content per directory. For example, maybe the layout will display
different banner images based on which directory the current page is in.
As usual, there
are a couple ways of dealing with this.
One is to grab the uri like we did in the previous section, and do
string processing on it to your heart's content. Not very fun.
Another way is to
define a property at the folder level, on each folder. Then, use the <cms:property> tag like
we did before, but with the attribute file="search" which will serach
up through parent folders for a place where the property is first defined.
For example,
create a folder named "Test" and set its Title property to
"testcontent." Then, create
an index.html and leave its Title blank.
If your template
includes an item:
<cms:property name="Title" file="search"/>
It will see that the Title is blank for the current file, then search upward and check the parent folder. Since the parent folder has it defined, it will display the parent folder's Title of "testcontent."
Previously, I talked about structured content, which is data in xml files, which can then be used to build page elements, such as a nav. This data can be edited using a nice gui:

To use structured content, first you must define the schema for the content. To do this, you create a file in the /system/modules/xxxxxxx/schemas directory (generally use the extension .xsd).
The easiest way, in my opinion, is to copy the schemas from the templateOne demo, and then edit them if necessary. I won't go into detail here about the format for creating the schemas. Read the examples to get an idea. Generally, though, a list of links can reuse templateOne's links.xsd schema.
Then, you need to create the actual content file for the data you want to use. Here's the rub: I haven't figured out the best way to do this yet. I just tend to copy an existing structured content file, and edit it. If I figure that out, I'll update this.
Or I18n, or whatever you want to call it. It refers to language translation. The problem: how to have multiple versions of the site, in different
languages, without having to go through the hassle of maintaining 2 different sites?
Well, this is
something that OpenCms makes relatively easy.
When you are editing page content, near the top, there is a dropdown for
selecting which language version of the file you want to edit.

This sets allows you to set the content for the page in all languages without having to have the same file repeated for each language.
Now, how do we show the different languages? Each file or folder has a property called locale. Usually it is left blank, which means to inherit from its parent (or use the default if all parents are blank). This property can be set with the 2-letter code for the locale you want to use. For example, to use the German version of a page, I set the locale for the page (or for the page's folder) to DE.
Now, you are probably asking, but how do I allow both versions to display, maybe with a different URL? Well, the best way I've found is to make use of OpenCms's "sibling" objects. A sibling in OpenCms is like a symbolic link in Unix operating system, except that there isn't necessarily one "master" copy of the file…. each sibling is treated equally.
So, I would recommend in your site's root directory, create a sibling of the entire site folder for each language you want to use. Name these folders like "en" or "de" and set the local property appropriately.


Now, because they are siblings, it doesn't matter which one you edit, they will all be editing the same thing.
One minor
recommendation: when you create the
locale-specific siblings, the new sibling will have a sibling directory for
each sibling you have already created (if you created your "de"
sibling first, then when you go to create the "en" sibling, it will
put a new "de" sibling under "en"). It's really no big deal, but to keep the
whole thing clean, and let you stop wondering if there's some sort of recursive
loop that will make your computer explode (or at least your head), it's handy
to delete these.
A question that
comes up a lot is, "How do I make OpenCms work with Struts?"
Ok, maybe that
doesn't come up a lot in the real world, but it did at my company. If you don't know what Struts is or don't
care, then skip this part, but I'm not going to explain what Struts is.
To incorporate Struts with OpenCms, the general idea is to have both the Struts servlet and the OpenCms servlet existing within the same tomcat webapp, with the webapp's web.xml managing the passing of requests to the appropriate servlet. Struts action requests will be sent to the Struts servlet, which will then perform the action code, and forward the browser to a new request that uses the OpenCms servlet to displaying the page.
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>OpenCmsServlet</servlet-name>
<url-pattern>/opencms/*</url-pattern>
</servlet-mapping>
This will ensure that the OpenCms servlet handles the requests for it's VFS, but the Struts servlet will handle all action requests.
One tricky part of incorporating struts with OpenCms is that you will need to slightly modify how you refer to the paths of the JSP's for the view. Instead of just doing "the-file.jsp", you will now need to refer to the full path of the file in the OpenCms's VFS, like "/opencms/directory-in-vfs/the-file-in-vfs.jsp". This, and similar modifications, will need to be done throughout your Struts configuration files, to ensure that the Jsp requests will be handled by the OpenCms servlet properly.
For example:
<action-mappings type="org.apache.struts...CustomActionMapping">
<action path="/welcome" forward="/opencms/welcome.jsp" >
<set-property property="example" value="EXAMPLE" />
</action>
</action-mappings>
Inside the .Jsp files, you can code in the same fashion as
any other Struts project, and use the tag libraries from Struts, or any other
custom tag libraries (including the OpenCms tag libraries)