Components are pieces of functionality that can be invoked by a handler or react to handler events. Components are a great way to re-use code between controllers, such as with pagination, searching, emailing, etc.
Import your desired components and include them in the components property on your handler, like so:
from ferris.components.pagination import Pagination
from ferris.components.json import Json
class Documents(Handler):
components = [Pagination, Json]
Inside of your actions, you can access the component instances using self.components:
def list(self):
self.components.pagination.paginate()
The ferris.components provides a few built-in components. These can be used directly, customized, or used as guidelines when building your own.
Provides automatic pagination of db.Query and ndb.Query objects.
Automatically happens for any list actions but can also be manually invoked via paginate().
In automatic operation, it looks for a template variable with the underscored pluralized version of the Handler’s name. For instance, if you’re on Pages it looks for the template variable pages.
Paginates a query and sets up the appropriate template variables.
Uses handler.paginate_limit to determine how many items per page, or defaults to 10 if omitted.
Sets the paging template variable to a dictionary like:
{
"cursor": "abc...",
"next_cursor": "nzb...",
"limit": 10
}
Returns the data, and if query_or_var_name is a string, sets that template variable.
For example of using this, see Extras
Provides some helper methods to send email using templates.
Sends an html email to recipient with the given subject and body.
The sender is automatically set to app_config['email']['sender'].
Any additionally arguments are passed to mail.send_mail, such as headers.
Renders a template and sends an email in the same way as send().
The current template context is used, so use Handler.set to bind any variables to the template.
For example:
from ferris.core.handler import Handler
from ferris.components.email import Email
class Example(Handler):
components = [Email]
def list(self):
self.set(text="Hello!")
self.components.email.send_template(
recipient="test@example",
subject="Test Email",
template="emails/test.html")
Assuming you have a template at emails/test.html.
Hooks into a handler to return json instead of rendering a template when the requestor asks for JSON.
The requestor can ask for json by adding ?alt=json to the URL, or by setting the Accepts header to application/json. You can also manually activate JSON in your handler by setting the render_as_json attribute.
By default, the json component will try to get the data to serialize using the following template variables: data, pluralize(handler), singularize(handler), edit_item, added_item, and item. You can specify additional variables to try by appending to the try_vars attribute.
For example:
from ferris.core.handler import Handler, scaffold
from ferris.components.json import Json
@scaffold
class Posts(Handler):
components = [Json]
@scaffold
def list(self):
pass
In this example, making a request to http://localhost:8080/posts will render an HTML template of all posts, but making a request to http://localhost:8080/posts?alt=json will return the list of posts as JSON.
The Upload component can take the guesswork out of using the Blobstore API to upload binary files. It works with Forms and Models.
Automatically handles file upload fields that need to use the blobstore.
This works by: * Detecting if you’re on an add or edit action (you can add additional actions with upload_actions, or set process_uploads to True) * Adding the upload_url template variable that points to the blobstore * Updating the form_action and form_encoding scaffolding variables to use the new blobstore action * Processing uploads when they come back * Adding each upload’s key to the form data so that it can be saved to the model
Does not require that the handler subclass BlobstoreUploadHandler, however to serve blobs you must subclass BlobstoreDownloadHandler.
A simple example:
from ferris.core.ndb import Model, ndb
from ferris.core.handler import Handler, scaffold
from ferris.components.upload import Upload
class Picture(Model):
file = ndb.BlobKeyProperty()
@scaffold
class Pictures(Handler):
components = [Upload]
The Search component makes it really use to use the Search API.
In order to use search, you must first index() your models:
Adds an instance of a Model into full-text search.
Parameters: |
|
---|
This is usually done in Model.after_put, for example:
def after_put(self):
index(self)
Be sure to unindex when an item is deleted or no longer needed:
Removes a document from the full-text search.
This is usually done in Model.after_delete, for example:
@classmethod
def after_delete(cls, key):
unindex(key)
With documents in the search index you can use the search component:
Provides a simple high-level interface to the App Engine Search API.
Searches using the provided index (or an automatically determine one).
Expects the search query to be in the query request parameter.
Also takes care of setting pagination information if the pagination component is present.
For example of using this, see Extras