| 297 | For the trunk version of Sahana Eden, all menu definitions have been implemented as functions in two classes: |
| 298 | |
| 299 | - '''S3MainMenu''' for the application main menu ("modules" menu) |
| 300 | - '''S3OptionsMenu''' for the options menus per module ("controller" menus) |
| 301 | |
| 302 | These classes can be found in {{{modules/eden/menus.py}}} and shall ''not'' be customized in place - instead, any custom menu definitions can happen in models/01_menu.py. The default version of 01_menu.py looks like: |
| 303 | |
| 304 | {{{ |
| 305 | # ========================================================================= |
| 306 | # Main menu |
| 307 | # |
| 308 | current.menu.main( |
| 309 | |
| 310 | # Standard modules-menu |
| 311 | S3MainMenu.menu_modules(), |
| 312 | |
| 313 | # Standard service menus |
| 314 | S3MainMenu.menu_help(right=True), |
| 315 | S3MainMenu.menu_auth(right=True), |
| 316 | S3MainMenu.menu_lang(right=True), |
| 317 | S3MainMenu.menu_admin(right=True), |
| 318 | S3MainMenu.menu_gis(right=True) |
| 319 | ) |
| 320 | |
| 321 | # ========================================================================= |
| 322 | # Controller menus |
| 323 | # |
| 324 | s3_menu_dict = { |
| 325 | |
| 326 | # Define custom controller menus here |
| 327 | |
| 328 | } |
| 329 | |
| 330 | }}} |
| 331 | |
| 332 | The first section defines the application main menu ("modules" menu). In the trunk version, this invokes the respective definition methods of '''S3MainMenu'''. To customize the main menu, you can simply comment the standard option and replace it by a custom definition, e.g.: |
| 333 | |
| 334 | {{{ |
| 335 | # ========================================================================= |
| 336 | # Main menu |
| 337 | # |
| 338 | current.menu.main( |
| 339 | |
| 340 | # Standard modules-menu, commented out |
| 341 | #S3MainMenu.menu_modules(), |
| 342 | |
| 343 | # Custom menu: |
| 344 | homepage(), # no parameters -> links to default/index |
| 345 | homepage("gis"), |
| 346 | homepage("pr", restrict=[ADMIN])( |
| 347 | MM("Persons", f="person"), |
| 348 | MM("Groups", f="group") |
| 349 | ), |
| 350 | MM("more", link=False)( |
| 351 | homepage("dvi"), |
| 352 | homepage("irs") |
| 353 | ), |
| 354 | |
| 355 | # Standard service menus |
| 356 | S3MainMenu.menu_help(right=True), |
| 357 | S3MainMenu.menu_auth(right=True), |
| 358 | S3MainMenu.menu_lang(right=True), |
| 359 | S3MainMenu.menu_admin(right=True), |
| 360 | S3MainMenu.menu_gis(right=True) |
| 361 | ) |
| 362 | }}} |
| 363 | |
| 364 | This example uses the {{{homepage}}} helper function to define a {{{MM}}} instance out of the module's nice name setting in 000_config. |
| 365 | |
| 366 | Mind the trailing commas! Note that you do not need to check for module activation - this happens automatically in check_active: items linked to deactivated controllers will automatically be deactivated. |
| 367 | |
| 368 | To customize a controller menu, you can override the standard menu in the s3_menu_dict, e.g.: |
| 369 | |
| 370 | {{{ |
| 371 | # ========================================================================= |
| 372 | # Controller menus |
| 373 | # |
| 374 | s3_menu_dict = { |
| 375 | |
| 376 | # Custom menu for the PR controller |
| 377 | "pr": M(c="pr")( # <- the menu itself has no label, just the controller |
| 378 | M("Persons", f="person")( # <- Sub-item, inherits c from the parent item |
| 379 | M("List"), # <- Sub-item, inherits both c and f from the parent item |
| 380 | M("New", m="create"), # <- method m will be appended to args, if not the last arg |
| 381 | M("Search", m="search"), # <- no need for T() of the label, happens automatically |
| 382 | ), |
| 383 | M("Groups", f="group")( |
| 384 | M("List"), |
| 385 | M("New", m="create"), |
| 386 | M("Search", m="search"), |
| 387 | ), |
| 388 | ), |
| 389 | } |
| 390 | }}} |
| 391 | |
| 392 | All controller menus which are not defined in s3_menu_dict fall back to the standard definition in S3OptionsMenu in modules/eden/menus.py. |
| 393 | |
| 394 | Options menus which are to be shared by multiple controllers must ''not'' define the controller in the root item, but instead at the first sub-item level. |
| 395 | |
| 396 | Items which shall match multiple functions can take a list of function names for the parameter f, where the first function name is used to render the URL, i.e.: |
| 397 | |
| 398 | {{{ |
| 399 | M("Persons", c="pr", f=["person", "index"]) |
| 400 | }}} |
| 401 | |
| 402 | is rendered as {{{/pr/person}}} but matches both {{{/pr/person}}} and {{{/pr/index}}}. |
| 403 | |