Backend and Frontend
The most important point you'll come across in any web framework is in splitting up the "frontend" and the "backend" code. This is absolutely necessary, even in small projects, or else the maintainability of your project will be in a very bad state. If you're an experienced web developer, you've probably already come across this idea and use it in your own projects.Rabbit forces you to distinguish between frontend and backend code. This means that if you choose to use Rabbit, you will have to split up your code accordingly. This is one of Rabbit's limitations -- the fact that you can't do it another way. It consiously works like that, as the reason for splitting up the code this way increases productivity overall, and lets other developers reading your code easily spot where everything is.
In short, the frontend code handles the presentation of your project, and how it interacts with your users. This may include, for instance, interface graphics, text, and styling. It may also include animations that appear to your user, localized strings, drag-and-drop functionality, the way that URLs appear in the address bar of their browser (pretty or ugly) and the icon that appears when they bookmark your pages. Anything that the user can in fact see is frontend.
The backend code handles internal things such as processing, storaging, and caching data as well as interaction with your databases. It is the base on which the frontend is developed. This may include, for instance, the system that stores and encrypts user passwords, compresses images uploaded by your users to save space on your web servers, and automatically deletes all comments posted on a blog post when the post itself is deleted.
Frontend code in Rabbit
Rabbit is designed to help you develop projects that are mainly web-oriented. However, it is not limited in this type of applications. Although the general concepts described here apply to any type of application you might need to develop, the structure used especially frontend-wise is very specific to the presentation mode that you will use. For example, CSS files can be applied to HTML source code for formatting, but not to LaTeX. Hence, in the following sections, we will describe the common approach when creating web applications that use standard technologies. If you desire to use a different interaction mechanism with your users, you will find the sections useful, but you will need to adapt them to your own presentation methods.Frontend code in Rabbit is structured in many ways differently from casual web-development frameworks. You might find this confusing to begin with if you are familiar with other concepts. However, the adopted structure allows for much more meaningful, extensible, and maintainable code once you understand the general way of thinking behind it.
Elements
The very basic part of all frontend code you will write when using Rabbit is called an Element. Each element is the most basic part of your frontend content description code and usually simply is responsible for outputting a small chunk of HTML code. It is crucial to make elements as short as possible, limiting the responsibility of each element to basic principles that "make sense". Elements should be limited to much less than 80 lines each. It's good if you can make each of your elements as small as about 20 - 30 lines long.Elements can invoke other elements, which can invoke elements on their own. That way, a hierarchical can be achieved, allowing elements to consist of several other "subelements". Looking at any website, can you imagine how it would be split up into elements? What would be the most basic element you can think of? How do elements group together to form larger chunks using subelements?
Understanding how elements split up will be beneficial in that it'll help you write more meaningful code, that will be oriented around your way of thinking as a web developer. It will make for more reusable and maintainable code in the long run.
Elements are stored in files, which can follow a hierarchical structure as well, using folders and subfolders. That way, elements can be grouped by their functionality, unrelated to whether they call each other or not. For example, all elements that are relevant to displaying photos and related content can be grouped within a folder. Then one of those elements can be invoked to display a photo stream inside a user profile page; the invoking element doesn't necessarily need to be grouped under the same folder.
For detailed information about elements, how to create them, and all their features, refer to the section Elements.
Master Elements
Some of the elements you define using the logic described above can be exported. Exporting an element marks it as a master element. Master elements are routed (linked to) particular URLs that can be used to directly invoke them. Hence, a user visiting a URL that is routed to a particular element will see that element rendered, along with its subelements.Actions
Actions are simple scripts that perform just that -- they execute user actions upon request. An action is usually the target of an HTML <form> (but doesn't necessarily need to be that). Actions perform the action in question and return the execution to a master element. They do not render content, nor display information to the user on their own.For example, an action could be "delete photo 54" that gets carried out by the relevant action file. The action file will perform the necessary permission checks to determine whether you actually have the rights to do the deletion, and then delete the photo. Finally, it will redirect you to a master element that will display a message for success or failure.
For detailed information about actions, how to create them, and all their features, refer to the section Actions.
A special type of actions, units are actions that are carried over AJAX. These are just like normal actions, but are invokable through the Coala AJAX API using Javascript. The special thing about units is the fact that they deserve different kind of handling due to, among others, data validation and compatibility issues, as well as the ability to be able to execute multiple units at-once.
For detailed information about units, how to create them, and all their features, refer to the section Units.
Actions and units are automatically exported for you, so they are by default accessible to the user through routed URLs. Finally, actions and units cannot perform nested calling like units can, so you cannot have subactions or subunits. However, they can be grouped by functionality into subdirectories, much like elements.
Extending the Frontend
Of course, if units, actions, and master elements do not suffice, you can create your own controller types easily by defining your own file structures. These might be useful for special (e.g. non-web-based) types of applications that have specific needs, different from what is usually expected. For information on how to extend Rabbit to support your own file types, refer to the section for extending Page. As a beginner, this is nothing you should worry about, however.Static files
Often, it is useful to contain structures that group together static files which are useful in web applications. Rabbit includes three basic folders that you can use for static content storage by default, but you can create your own also:- The "images" directory can be used to store graphics and images.
- The "css" directory can be used to store CSS stylesheets.
- The "js" directory can be used to store Javascript files.
If your projects grows large enough, you might have to split those across different servers, or use a different structure. The default Rabbit structure includes them for your convenience in mind, but does not require that you use them.
Backend code in Rabbit
Backend code in Rabbit is more generalized, as it isn't oriented around a particular type of service rendering requirement such as web-based services.Libraries
Backend code is split into libraries each of which defines a very particular type of functionality. Following the Rabbit philosophy, the purpose of each library must be clearly defined and disjoint from the rest of the backend. For example, you can have a library for handling user details storage and encryption. A different library could handle forum posts, while another could handle forum comments.Many libraries work together with each other towards a common goal. For instance, the forum library in the example above might need to query the number of comments per forum from the comments library. This type of cooperation between libraries is common and encouraged. Having libraries that use other libraries introduces the need for library dependancies, which can be clearly specified in Rabbit. Finally, library dependancies must also be defined by frontend parts such as elements, actions, or units.
For more information about libraries, how to create them, and their extended functionality, refer to the section Libraries.
Unit tests
Rabbit encourages you to follow a behavior-driven design pattern, or at least a test-driven design pattern. Experience shows that defining unit tests (and the API) prior to implementation is crucial in the productivity and the success of a project. Although all parts of a project must be tested if possible, backend testing is the most important part. As frontend testing can be done using external utilities, Rabbit offers a testing suite that allows you to test your backend libraries accordingly. The unit testing suite that Rabbit offers is based on Beck's unit testing framework, very similar to jUnit or other famous testing platforms.Unit tests in Rabbit are defined separately from the library implementations and can be split from production if required. You aren't required to write unit tests, but the framework supports you if you desire to perform this type of development.
For more information about unit tests in Rabbit, how to create them, how to run them, and their particular features, refer to the section Unit Testing.