Skip to content

fix docs code tag #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/docs/guide/configuration/accessing_plugin_config.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ your plugin, automatically namespace for your plugin using the @plugin.<pluginNa

So in a service you can trivially access this config inside a service or controller for example:

{docx}
{code}
class MyPluginService {
def doSomething() {
if (pluginConfig.enabled) {
println "It worked!"
}
}
}
{docx}

{code}
4 changes: 2 additions & 2 deletions src/docs/guide/configuration/changing_config.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The code uses a simple DSL that is identical to normal Config except:

The application Config is loaded first. All the doWithConfig blocks are evaluated and the results merged in.

{docx}
{code}
def doWithConfig = { config ->
platformUi {
ui.Bootstrap.button.cssClass = 'btn'
Expand All @@ -21,6 +21,6 @@ def doWithConfig = { config ->
grails.x.y = config.p.q == 'something' ? true : false
}
}
{docx}
{code}

See [doWithConfig|pluginConventions] for more details.
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ This allows the platform to warn users when they mistype a config name or supply

Do declare the options your plugin supports, add the @doWithConfigOptions@ closure to your plugin descriptor:

{docx}
{code}
def doWithConfigOptions = {
'organization.name'(type: String, defaultValue: 'My Corp (set plugin.platformCore.organization.name)')
'site.name'(type: String, defaultValue: 'Our App (set plugin.platformCore.site.name)')
}
{docx}
{code}

This block, from the platform core, defines two configuration values of type String, with a default value.

You can also supply a custom validator:

{docx}
{code}
def doWithConfigOptions = {
'concurrentConnections'(type: Integer, defaultValue: 10,
validator: { v -> v < 500 ? null : 'concurrent.connections.too.big' }
}
{docx}
{code}

Behaving just like constraint validators, your validator returns null for "ok" or an i18n message string for the error.

Expand Down
8 changes: 4 additions & 4 deletions src/docs/guide/events.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ and get maximum flexibility when required :

In a nutshell, you will :
* Send events :
{docx}
{code}
class UserController{

def registration(){
Expand All @@ -45,10 +45,10 @@ class UserController{
}
}
}
{docx}
{code}

* Write listeners (or event handler, or event reactor or whatever you call it):
{docx}
{code}
class UserService{

//use method name 'mailRegistration' as topic name
Expand All @@ -72,4 +72,4 @@ class UserService{
}
}
}
{docx}
{code}
6 changes: 3 additions & 3 deletions src/docs/guide/events/artifact.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ timeout | Long | | Default timeout for execution time, throwing a TimeoutExcept
\* | \* | | Any attributes can be written to be used by plugins through EventDefinition.othersAttributes
{table}

{docx}
{code}
events = {
//prevents any events in gorm namespace
'*' namespace:'gorm', disabled:true
Expand Down Expand Up @@ -74,8 +74,8 @@ events = {
//testTopic9 onError:'anotherTopicErrors', onReply:'anotherTopicReplies'

}
{docx}
{code}

h3. Reloading in Development mode

It works.
It works.
4 changes: 2 additions & 2 deletions src/docs/guide/events/config.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Based on Platform-Core [configuration|guide:configuration] mechanism, the plugin
{table}

In addition, you can override beans values such as gormTopicSupport
{docx}
{code}
beans{
gormTopicSupport {
//transform gorm Events Objects types into topics
Expand All @@ -22,4 +22,4 @@ beans{
]
}
}
{docx}
{code}
12 changes: 6 additions & 6 deletions src/docs/guide/events/gorm.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Same listeners behaviors apply, e.g. using EventMessage for the argument type, u
Because listeners are called if there are *no arguments* or the argument *type is assignable to current event data type*, specifying
a domain class is the only required step to filter domains events.

{docx}
{code}
class SomeService{

@Listener(namespace = 'gorm')
Expand All @@ -39,21 +39,21 @@ class SomeService{
}

}
{docx}
{code}

h3. Filtering with Events Artifact

Setting a filter through an Events artifact allows more fined control and efficient selection since it prevents events to be
propagated :

{docx}
{code}
events = {
'afterInsert' namespace:'gorm', filter:Book
'afterDelete' namespace:'gorm', filter:{it.id > 5}
'afterUpdate' namespace:'gorm', filter:{it in Book || it in Author}
'beforeDelete' namespace:'gorm', disabled:true
}
{docx}
{code}

{note}
GORM may generate tons of events. Consider using it wisely, combine it with routing filtering.
Expand All @@ -71,7 +71,7 @@ If a listener handles one of the _before\*_ topics and returns a boolean value,
* Returning *false* will cancel the current database write
* Returning *true* will just let the chain continuing

{docx}
{code}
class SomeService{

//veto any Book insert
Expand All @@ -80,4 +80,4 @@ class SomeService{
false
}
}
{docx}
{code}
34 changes: 17 additions & 17 deletions src/docs/guide/events/listening.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ h3. Defining listeners at compile time

Within Grails services you can use the *@Listener* annotation. It takes a *topic* string, but you can omit it and use the *method name* as the topic to listen for:

{docx}
{code}
class SomeService{

@grails.events.Listener(topic = 'userLogged')
Expand All @@ -18,12 +18,12 @@ class SomeService{
def mailSent(){
}
}
{docx}
{code}

Event methods can define a *single argument*, and the value is the object sent with the event. Usually this is the "subject" of the event.
However an event is carried by an enveloppe called EventMessage which contains several useful metadata like additionnal headers, current topic :

{docx}
{code}
class SomeService{

@grails.events.Listener(topic = 'userLogged')
Expand All @@ -33,7 +33,7 @@ class SomeService{
println userMessage.data // displays data
}
}
{docx}
{code}

If a listener argument type is not assignable to an event data type, the event *silently skips the mismatching listener*. If you want to catch
every event types, use Object type or if the argument is not necessary, do not declare it.
Expand All @@ -47,7 +47,7 @@ h3. Namespacing

Your declared events belongs to the *app* namespace, unless you tune it using the *namespace* argument or the Events DSL we will introduce later.

{docx}
{code}
class SomeService{

@grails.events.Listener(topic = 'userLogged', namespace = 'security')
Expand All @@ -59,17 +59,17 @@ class SomeService{
def afterInsert(User user){
}
}
{docx}
{code}

Remember that you will need to specify the scope when triggering events if you customize it with a different value than *app* :

{docx}
{code}
class SomeController{
def myAction(){
event for:'security', topic:'userLogged', data:session.user
}
}
{docx}
{code}

{warning}
It's mandatory to declare namespace when using events bus from a plugin in order to avoid any conflicts.
Expand All @@ -79,7 +79,7 @@ h3. Proxy (AOP) support

By default, listeners try to call the original method (unproxified bean). Using *proxySupport* you can tweak this setting :

{docx}
{code}
class SomeService{

static transactional = true
Expand All @@ -90,13 +90,13 @@ class SomeService{
}

}
{docx}
{code}

h3. Dynamic listeners

Some edge cases need runtime registration. If you meet this use case, use the injected [on|eventsMethods] method :

{docx}
{code}
class SomeController{

def testInlineListener = {
Expand All @@ -115,13 +115,13 @@ class SomeController{
render "$listener registered"
}
}
{docx}
{code}

h3. Wildcard support

Capturing a wider group of events can be useful, specially for monitoring purposes. It's possible to listen for multiple topics/namespaces in a single shot using *wildcard as the last character*.

{docx}
{code}
class SomeService{

@grails.events.Listener(namespace='role-*', topic = 'chat-*')
Expand All @@ -130,7 +130,7 @@ class SomeService{
println userMessage.event
}
}
{docx}
{code}

{note}
This feature will probably evolve to a smarter implementation behaving like UrlMappings and authorizing substring captures
Expand All @@ -147,7 +147,7 @@ The above square brackets determine each optional part of the sequence id thus a
This pattern is useful when using *countListeners*, *removeListeners* or *extensions*. For instance, overriding
a generated *channel* with *events-si* plugin requires to use @namespace://topic@ if _namespace_ is different from "app".
Another example to count listeners:
{docx}
{code}
//count every listeners subscribed to 'mytopic' inside TestService
countListeners("mytopic:my.TestService")

Expand All @@ -156,8 +156,8 @@ countListeners("gorm://*")

//remove every listeners in TestService
removeListeners("*:my.TestService")
{docx}
{code}

h3. Reloading in Development mode

It works.
It works.
20 changes: 10 additions & 10 deletions src/docs/guide/events/replying.gdoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ h3. Simple reply

Replying is a simple matter of returning an object from the listener method :

{docx}
{code}
class SomeService{
@Listener
def logout(User user){
Expand All @@ -17,12 +17,12 @@ class SomeService{
return disconnectDate
}
}
{docx}
{code}

If listeners return non null objects, the caller can access them through the EventReply enveloppe returned immediatly
after calling *event* method. The other option is the use of a *reply handler* :

{docx}
{code}
class SomeController{

def logout(){
Expand All @@ -41,7 +41,7 @@ class SomeController{
render reply_future.get(30, TimeUnit.SECONDS)
}
}
{docx}
{code}

{note}
Whenever an event is triggered, a task is submitted into the events bus thread pool and a Future returned, wrapped into EventReply.
Expand All @@ -55,7 +55,7 @@ Multiple listeners can return values for the same topic/namespace. In this case,
Remember that a valid result is a non null value, hence why even if 3 handlers have reacted but only 2 did return something, then you will only
see 2 values in the *EventReply.values*.

{docx}
{code}
class SomeController{

def logout(){
Expand All @@ -68,7 +68,7 @@ class SomeController{
render reply.values
}
}
{docx}
{code}

h3. Exceptions

Expand All @@ -83,7 +83,7 @@ An *onError* parameter is available and accepts a *Closure{List<Throwable> error
Exceptions in multiple listeners scenario don't interrupt the execution flow and leave a chance to others listeners to execute as well.
The return value from a failing listener becomes the raised exception.

{docx}
{code}
class SomeController{

def logout(){
Expand Down Expand Up @@ -111,15 +111,15 @@ class SomeController{

}
}
{docx}
{code}

h3. Waiting replies

In domains, services and controllers artefacts you can wait for events using "EventReply[] waitFor(EventReply... eventReplies)".
It accepts as many events replies you want and returns the same array for functiunal programming style.
EventReply also have a waitFor method for one-line waiting.

{docx}
{code}
class SomeController{

def logout(){
Expand All @@ -142,4 +142,4 @@ class SomeController{

}
}
{docx}
{code}
Loading