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 5.5.9
    2. Class loader initialization
    3. Obtain Grav instances


      1. No instance exists, so call load()
      2. Add grav
      3. Initialize the debugger and add it to debugger
      4. Register the log handler
      5. Register the error handler
      6. Add uri
      7. Add task
      8. Add events
      9. Add cache
      10. Add session
      11. Add plugins
      12. Add themes
      13. Add twig
      14. Add taxonomy
      15. Add language
      16. Add pages
      17. Add assets
      18. Add page
      19. Add output
      20. Add browser
      21. Add base_url_absolute
      22. Add base_url_relative
      23. Add base_url
      24. Register the stream handler
      25. Register the config handler
    4. call $grav->process()


      1. Initialize the configuration
      2. Initialize the Session
      3. Initialize the Uri object
      4. Initialize the error handler
      5. Initialize the debugger
      6. Start output buffering
      7. Initialize the timezone
      8. Initialize the plugins
      9. Fire onPluginsInitialized event
      10. Initialize the theme
      11. Fire onThemeInitialized event
      12. Fire onTask[TASK] event
      13. Initialize assets
      14. Fire onAssetsInitialized event
      15. Initialize twig


        1. Set Twig template paths based on configuration
        2. Handle language templates if available
        3. Fire onTwigTemplatePaths event
        4. Load Twig configuration and loader chain
        5. Fire onTwigInitialized event
        6. Load Twig extensions
        7. Fire onTwigExtensions event
        8. Set standard Twig variables (config, uri, taxonomy, assets, browser, etc)
      16. Initialize pages


        1. Call buildPages()
        2. Check if cache is good
        3. If cache is good load pages date from cache
        4. If cache is not good call recurse()
        5. Fire onBuildPagesInitialized event in recurse()
        6. If a .md file is found:


          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 _
        7. Fire onPageProcessed event
        8. If a folder found recurse() the children
        9. Fire onFolderProcessed event
        10. Call buildRoutes()
        11. Initialize taxonomy for all pages
        12. Build route table for fast lookup
      17. Fire onPagesInitialized event
      18. Fire onPageInitialized event
      19. Add the debugger CSS/JS to the assets
      20. Get Output with Twig's processSite() method


        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
      21. Fire onOutputGenerated event
      22. Set the HTTP headers
      23. Echo the output
      24. Flush the output buffers to the page
      25. Fire onOutputRendered event
      26. Connection to client is closed
      27. Fire onShutdown event

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

  • Page.php

    1. Fire onPageContentRaw event
    2. Process the page according to Markdown and Twig settings. Fire onMarkdownInitialized event
    3. Fire onPageContentProcessed event