Grav Lifecycle

It is often useful to know how Grav processes in order to fully understand how best to extend Grav via plugins. This is the Grav lifecycle:

index.php

  1. Check PHP version to ensure we're running at least version 7.1.3
  2. Class loader initialization
  3. Obtain Grav instance

    Grav.php

    1. No instance exists, so call load()
    2. Add loader
    3. Add and initialize debugger
    4. Add grav (deprecated)
    5. Register Default Services
    6. Register Service Providers
      1. Accounts Service Provider
        1. Add permissions (1.7)
        2. Add accounts (1.6)
        3. Add user_groups (1.7)
        4. Add users (deprecated)
      2. Assets Service Provider
        1. Add assets
      3. Backups Service Provider
        1. Add backups (1.6)
      4. Config Service Provider
        1. Add setup
        2. Add blueprints
        3. Add config
        4. Add languages
        5. Add language
      5. Error Service Provider
        1. Add error
      6. Filesystem Service Provider
        1. Add filesystem
      7. Flex Service Provider
        1. Add flex (1.7)
      8. Inflector Service Provider
        1. Add inflector
      9. Logger Service Provider
        1. Add log
      10. Output Service Provider
        1. Add output
      11. Pages Service Provider
        1. Add pages
        2. Add page
      12. Request Service Provider
        1. Add request (1.7)
      13. Scheduler Service Provider
        1. Add scheduler (1.6)
      14. Session Service Provider
        1. Add session
        2. Add messages
      15. Streams Service Provider
        1. Add locator
        2. Add streams
      16. Task Service Provider
        1. Add task
        2. Add action
      17. Simple Service Providers
        1. Add browser
        2. Add cache
        3. Add events
        4. Add exif
        5. Add plugins
        6. Add taxonomy
        7. Add themes
        8. Add twig
        9. Add uri
  4. call Grav::process()

    Grav.php

    1. Run Initialize Processor
      1. Configuration
        1. Initialize $grav['config']
        2. Initialize $grav['plugins']
      2. Logger
        1. Initialize $grav['log']
      3. Errors
        1. Initialize $grav['errors']
        2. Registers PHP error handlers
      4. Debugger
        1. Initialize $grav['debugger']
      5. Handle debugger requests
      6. Start output buffering
      7. Localization
        1. Set the locale and timezone
      8. Plugins
        1. Initialize $grav['plugins']
      9. Pages
        1. Initialize $grav['pages']
      10. Uri
        1. Initialize $grav['uri']
        2. Add $grav['base_url_absolute']
        3. Add $grav['base_url_relative']
        4. Add $grav['base_url']
      11. Handle redirect
        1. Redirect if system.pages.redirect_trailing_slash is true and trailing slash in URL
      12. Accounts
        1. Initialize $grav['accounts']
      13. Session
        1. Initialize $grav['session'] if If system.session.initialize is true
    2. Run Plugins Processor
      1. Fire onPluginsInitialized event
    3. Run Themes Processor
      1. Initialize $grav['themes']
      2. Fire onThemeInitialized event
    4. Run Request Processor
      1. Initialize $grav['request']
      2. Fire onRequestHandlerInit event with [request, handler]
      3. If response is set inside the event, stop further processing and output the response
    5. Run Tasks Processor
      1. If request has attribute controller.class and either task or action:
        1. Run the controller
        2. If NotFoundException: continue (check task and action)
        3. If response code 418: continue (ignore task and action)
        4. Else: stop further processing and output the response
      2. If task:
        1. Fire onTask event
        2. Fire onTask.[TASK] event
      3. If action:
        1. Fire onAction event
        2. Fire onAction.[ACTION] event
    6. Run Backups Processor
      1. Initialize $grav['backups']
      2. Fire onBackupsInitialized event
    7. Run Scheduler Processor
      1. Initialize $grav['scheduler']
      2. Fire onSchedulerInitialized event
    8. Run Assets Processor
      1. Initialize $grav['assets']
      2. Fire onAssetsInitialized event
    9. Run Twig Processor
      1. Initialize $grav['twig']

        Twig.php

        1. Set Twig template paths based on configuration
        2. Handle language templates if available
        3. Fire onTwigTemplatePaths event
        4. Fire onTwigLoader event
        5. Load Twig configuration and loader chain
        6. Fire onTwigInitialized event
        7. Load Twig extensions
        8. Fire onTwigExtensions event
        9. Set standard Twig variables (config, uri, taxonomy, assets, browser, etc)
    10. Run Pages Processor
      1. Initialize $grav['pages']

        Pages.php

        1. Call buildPages()
        2. (logic differs somewhat for Flex Pages, but the idea is the same)
        3. Check if cache is good
        4. If cache is good load pages date from
        5. If cache is not good call recurse()
        6. Fire onBuildPagesInitialized event in recurse()
        7. If a .md file is found:

          Page.php

          1. Call init() to load the file details
          2. Set the filePath, modified, id
          3. Call header() to initialize the header variables
          4. Call slug() to set the URL slug
          5. Call visible() to set visible state
          6. Set modularTwig() status based on if folder starts with _
        8. Fire onPageProcessed event
        9. If a folder found recurse() the children
        10. Fire onFolderProcessed event
        11. Call buildRoutes()
        12. Initialize taxonomy for all pages
        13. Build route table for fast lookup
      2. Fire onPagesInitialized event with [pages]
      3. Fire onPageInitialized event with [page]
      4. If page is not routable:
        1. Fire onPageNotFount event with [page]
      5. If task:
        1. Fire onPageTask event with [task, page]
        2. Fire onPageTask.[TASK] event with [task, page]
      6. If action:
        1. Fire onPageAction event with [action, page]
        2. Fire onPageAction.[ACTION] event with [action, page]
    11. Run Debugger Assets Processor
      1. Debugbar only: Add the debugger CSS/JS to the assets
    12. Run Render Processor
      1. Initialize $grav['output']
      2. If output instanceof ResponseInterface:
        1. Stop further processing and output the response
      3. Else:
        1. Render page with Twig's processSite() method

          Twig.php

          1. Fire onTwigSiteVariables event
          2. Get the page output
          3. Fire onTwigPageVariables, also called for each modular subpage
          4. If a page is not found or not routable, first fire the onPageFallBackUrl event to see if we have a fallback for a media asset and then fire onPageNotFound if not
          5. Set all Twig variables on the Twig object
          6. Set the template name based on file/header/extension information
          7. Call render() method
          8. Return resulting HTML
        2. Fire onOutputGenerated event
        3. Echo the output into output buffer
        4. Fire onOutputRendered event
        5. Build Response object
        6. Stop further processing and output the response
    13. Output HTTP header and body
    14. Render debugger (if enabled)
    15. Shutdown
      1. Close session
      2. Close connection to client
      3. Fire onShutdown event

Whenever a page has its content() method called, the following lifecycle occurs:

Page.php

  1. If content is NOT cached:
    1. Fire onPageContentRaw event
    2. Process the page according to Markdown and Twig settings. Fire onMarkdownInitialized event
    3. Fire onPageContentProcessed event
  2. Fire onPageContent event

Found errors? Think you can improve this documentation? Simply click the Edit link at the top of the page, and then the icon on Github to make your changes.