Streams are used to asynchronously load batches of content entries which may can be filtered or sorted. The most common type of stream is the WallStream used for example on the dashboard or space stream view. Besides WallStreams the HumHub core only implements one additional stream type, the activity sidebar stream. The following section describes how to implement custom streams and extend existing streams.
Content::$stream_channel property defines the default stream type of this content. If not
otherwise defined the 'default' stream channel will be used, which means this content will be included in wall streams as
the space, profile or dashboard stream.
ContentActiveRecord::$streamChannel property of your custom content type can be used to overwrite the default stream type.
Its common practice to set
$this->streamChannel = null for certain records in order to exclude specific entries from the
default wall streams. An example of a custom stream channel is the activity stream. Activity records are not included in
the wall streams but are part of an activity sidebar stream.
Exclude all instances from default wall streams:
Exclude specific entries from default wall streams:
For your custom
ContentActiveRecord you can consider the following stream channel options:
- default: this stream channel will include your content to space/profile walls and the dashboard
- null will exclude the content from the default wall streams (space/profile/dashboard)
- Use a custom stream channel if you exclusively want your content to be included in your own custom stream
Note: A custom stream channel should be unique, so choose a meaningful name preferably with module prefix.
StreamEntryWidget is responsible for rendering stream entries. The
is the base widget class for all types of stream entries. The default stream widget class of a content type
is defined by the
ContentActiveRecord::$wallEntryClass property. For wall streams there are two different widget
types available, the
WallStreamEntryWidget renders a post style wall entry with user image and name in the head part of the wall entry.
This widget type should be used for content which emphasizes the author of the content and contains mainly personal
(not collaborative) content. For content with collaborative nature you should rather use the
When extending a
WallStreamEntryWidget you'll have to implement the
which will be embedded in the content section of your stream entry.
WallStreamModuleEntryWidget does not emphasize the user, but instead the content type and the content title.
This widget should be used for content types in which the author is not that important as for example a wiki or other
WallStreamModuleEntryWidget you'll have to implement the
well as the
WallStreamEntryWidget::getTitle() function. You may also want to overwrite the
function to overwrite the default icon provided by
The WallEntryControls menu is part of all wall stream entries and includes stream links as Delete or Edit. The following links are added to the wall entry by default (depending on the user permission and view context):
- PermaLink: Opens a modal with the content url
- DeleteLink: Used to delete an entry
- EditLink: Used to edit an entry
- VisibilityLink: Used to switch the visibility of a content
- NotificationSwitchLink: Used enable/disable receiving notifications for a content.
- PinLink: Used to pin/unpin content entries to a stream
- MoveContentLink: Used to move a content entry to another space
- ArchiveLink: Used to archive/unarchive an entry
- TopicLink: Used to manage topics of a content entry
WallStreamModuleEntryWidget::getControlsMenuEntries() your content type can add additional menu entries to
the controls menu of your content type follows:
You can also disable default entries as follows:
StreamEntryWidget::$renderOptions property can be used to configure the appearance of an wall entry, for example by:
- Disabling controls menu entries
- Disabling the whole controls menu
- Disabling certain stream entry addons
- Changing the output depending on the view context
The appearance of a stream entry may differentiate depending on a view context configuration. Wall entries on the dashboard for example include further information about the container the content is assigned to. Posts in the detail view display the whole content without the use of a collapsed read-more section. The default streams support the following view contexts:
StreamEntryOptions::VIEW_CONTEXT_DEFAULT: Default appearance (e.g. on space/profile stream)
StreamEntryOptions::VIEW_CONTEXT_DASHBOARD: Dashboard stream
StreamEntryOptions::VIEW_CONTEXT_SEARCH: Content search stream
StreamEntryOptions::VIEW_CONTEXT_DETAIL: Detail view (single entry stream)
StreamEntryOptions::VIEW_CONTEXT_MODAL: Rendered within a modal dialog
WallStreamEntryWidget::$editRoute is defined an edit menu item will be added to the controls menu in case the current
user is allowed to edit the content. The
WallStreamEntryWidget::$editMode defines how the content should be edited e.g.
within a modal, inline, or within a new page.
There are the following edit modes available:
EDIT_MODE_MODALthe response of
editRouteaction will be loaded into a modal.
EDIT_MODE_INLINEthe response of
editRouteaction will be embeded into the WallEntry content.
EDIT_MODE_NEW_WINDOWthe page response of
editRouteaction will be fully loaded.
You can add custom streams as for example own wall or sidebar streams to your custom module. A custom stream implementation contains of the following components:
- Stream action responsible for handling stream requests
- StreamQuery responsible for fetching and filtering the stream result
- StreamViewer widget responsible for rendering the stream container in the view
- Stream filter navigation (optional) can be used to render a filter navigation for your stream
The following sections explain the different components of a stream by implementing a custom content info stream. Our custom stream will render stream entries in form of content metadata blocks by extending the dashboard stream. Furthermore, we'll add an additional custom filter to only include content created by the current user (if active).
humhub\modules\stream\widgets\StreamViewer widget is used to render our custom stream. Note, the stream entries of
a stream are loaded asynchronously and therefore will not directly be rendered by the StreamViewer widget itself.
The StreamViewer widget expects a
streamAction property pointing to the controller action handling stream requests.
streamFilterNavigation can be used to define a stream filter navigation widget class.
Wall streams come with a default stream filter navigation. In case you want to disable the default navigation
for your custom stream, just set
streamFilterNavigation to false or null.
The stream filter navigation can be used to add additional filter options to your stream. In our content info stream we replace the default filter navigation with a custom filter navigation widget. The filter navigation will include a single checkbox filter which will only include content created by the current user if active.
In our example we render a very simple and static filter navigation, for more complex and extendable stream navigations,
you might want to work with separated filter blocks and panels, see
In such cases we would register the filters within
initFilters instead of directly rendering them in the view.
The view of our filter navigation widget looks like the following:
The filter in the previous example will be added to the default
filters request parameter.
In case you want to use another parameter you need to overwrite the
category property of your filter input.
Stream filters extend
humhub\modules\stream\models\filters\StreamQueryFilter and can be used to add query conditions
to your stream query. In the following example we implement our
humhub\modules\stream\actions\Stream is the base controller action class
for all streams responsible for handling stream results. The HumHub core provides the following default stream actions:
ContentContainerStream: Includes an optional content container filter and should be used for streams on container level, e.g. include all content of content type x in space y.
DashboardStreamAction: Includes dashboard content visibility filters
In this example we register our action and register our custom filter handler. Furthermore, we overwrite the widget class used to render the stream entries.
In case you have a more complex custom stream scenario, or want your stream action to be extendable by events you can consider implementing a custom stream action as follows:
You can also consider implementing a reusable stream query class as follows:
Since we do not want to use the default entry layout in our content info stream, we need to implement a custom
Since HumHub v1.3 you are able to extend the stream filter navigations by implementing following event handlers:
WallStreamQuery::EVENT_BEFORE_FILTERto add the filter to the query
WallStreamFilterNavigation navigation contains three filterPanels:
Each panel can contain multiple filterBlocks. Each block may contain multiple filters sorted by a
setting. The following example adds an
originator filter to the wall stream:
Event handler implementation: