Skip to content
Snippets Groups Projects
  1. Sep 15, 2024
  2. Sep 14, 2024
  3. Sep 11, 2024
  4. Sep 10, 2024
  5. Aug 30, 2024
    • Christian Kuhn's avatar
      [FEATURE] Implement and use a core ViewFactoryInterface · c22b72cd
      Christian Kuhn authored
      After a long list of preparation and side patches, this
      change introduces a central ext:core ViewFactoryInterface
      plus a default implementation for fluid, and rolls it out.
      
      We established a sub section of a generic view for backend
      modules with ext:backend BackendViewFactory in TYPO3 v12
      already. This worked out well. The patch picks this up
      with a global factory interface for all other use
      cases that need to deal with views.
      
      This ultimately allows instances to change any view rendered
      by any component by configuring the instance to inject a
      different ViewFactoryInterface implementation to some
      controller and let it return an ext:core ViewInterface that
      uses some different view implemenation like Twig or whatever
      floats your boat. This is also very helpful for headless
      implementations to transparently substitute casual html
      rendering with for instance a json result.
      
      The patch decouples fluid much better and obsoletes the custom
      fluid view implemen...
      c22b72cd
  6. Aug 28, 2024
  7. Aug 27, 2024
    • Benni Mack's avatar
      [FEATURE] Automatically resolve relations for records · 43a284ca
      Benni Mack authored
      What does it do? When creating a record
      object out of a database row (via the RecordFactory),
      the Record object now holds enriched values
      for fields where the content is "known" based
      on TCA / Schema API.
      
      This is especially relevant for records with
      possible relations, for field types such as
      "type=group", "type=select" with foreign_table set
      and "type=inline" as an example.
      
      The main purpose for this relation enriching
      is rendering of the backend page module and
      content in frontend, but it can be used
      for any kind of TCA-based record.
      
      It also works recursively and with circular
      dependencies thanks to the RecordIdentityMap.
      
      In order to avoid any problems with large amounts
      of data, an approach of "Lazy+Greedy Fetching"
      was chosen.
      
      How does this approach work under the hood?
      
      As an example, we load 10 content elements on a
      page (1 DB query) so we can render them.
      
      Step 1: Lazy Collections / RecordPropertyClosure
      
      RecordFactory filters out only the relevant
      fields and their values from a record's type.
      Now, the RecordFactory also checks for fields
      with their meaning and uses a different value for
      a field. Example: For a type=inline value, there
      was the number "5" as value (= 5 relations) available,
      now we know we need the relation records (as a collection)
      properly sorted resolved there as well. For this to
      work, the new RecordFieldTransformer creates
      LazyCollection objects or RecordPropertyClosure objects
      (for a 1:1/n:1 relation) which means that the DB query is
      not made (yet) but only called when the value is accessed
      for the first time ("lazy loading").
      
      Step 2: Getting the related UID/Table Pairs
      
      The RecordIdentityMap now knows about the
      10 Records from tt_content, as they have been created
      completely before handing it to the output rendering.
      There comes the fun part. As soon as the value (with a
      lazy closure) is accessed for the first time,
      the RelationResolver checks the RelationHandler
      to find the table / uids that we should resolve.
      
      In our case, we now know that our first content element
      has 5 relations to a DB table e.g. "tx_mycarousel_item"
      with UIDs 12,13,14,15,16. Thanks to the RelationHandler,
      we also have the proper sorting of these items.
      
      Step 3: A greedy database query to get the full DB rows
      
      So, for the first content element, we want the 5
      complete, related DB rows. The RelationResolver
      now sends this query to the "GreedyDatabaseBackend"
      which uses a subquery to not only fetch
      the 5 DB rows, but ALL rows of this DB table
      that are on the same PID with 1 DB query (using subselects).
      
      It however only returns the 5 items, and keeps the
      other items in a runtime cache.
      
      At this point we have made 3 DB queries.
      
      Currently, we then do the language + workspace overlays.
      
      Step 4: The long way back
      
      The RelationResolver now has the full DB rows and sorts
      them. The RecordFieldTransformer builds Record / Collection
      objects out of it, checks if an object has been created
      already (via the IdentityMap) or creates new ones,
      utilizing again the Lazy approach from step 1 to ensure
      we only resolve the records when we need them.
      
      Responsibilities:
      
      - RecordFieldTransformer
        - knows what to do based on the Field Type
        - returns objects, never raw DB records
        - initializes the lazy collections / closure objects
      - RelationResolver
        - uses RelationHandler to resolve uids
        - knows and applies the sorting
      - GreedyDatabaseBackend
        - does overlays / enableFields
      
      The design decisions behind this approach:
      - We only build Record objects when they are requested explicitly
      - We distinguish the cardinality (1:1 / n:1 vs. 1:n)
      - We do overlays on a very end of the chain
      
      Kudos to Nikita Hovratov for creating the first draft
      of this approach here: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83725
      along with comprehensive tests.
      
      PS: In the mid-term, the RelationResolver could be
      based on the sys_refindex and minimize queries.
      
      Resolves: #103581
      Related: #103783
      Related: #104002
      Releases: main
      Change-Id: I73d1f017c5f98115f7ad4ddd2634b7acf66d183c
      Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/85046
      
      
      Tested-by: default avatarOliver Bartsch <bo@cedev.de>
      Reviewed-by: default avatarNikita Hovratov <nikita.h@live.de>
      Reviewed-by: default avatarOliver Bartsch <bo@cedev.de>
      Tested-by: default avatarcore-ci <typo3@b13.com>
      Tested-by: default avatarNikita Hovratov <nikita.h@live.de>
      Tested-by: default avatarBenjamin Franzke <ben@bnf.dev>
      Reviewed-by: default avatarBenjamin Franzke <ben@bnf.dev>
      43a284ca
  8. Aug 20, 2024
  9. Aug 15, 2024
  10. Aug 14, 2024
  11. Aug 06, 2024
  12. Jul 29, 2024
  13. Jul 25, 2024
  14. Jul 23, 2024
  15. Jul 18, 2024
  16. Jul 15, 2024
  17. Jul 12, 2024
  18. Jul 11, 2024
  19. Jul 09, 2024
  20. Jun 28, 2024
  21. Jun 27, 2024
    • Benni Mack's avatar
      [FEATURE] Make parseFunc allowTags and denyTags optional · 4da2551c
      Benni Mack authored
      Since HTML Sanitizer was introduced, lib.parseFunc does
      "transformations", instead of ensuring that HTML is
      "safe", which wasn't possible anyways (that was one
      of the reasons why htmlSanitize is introduced).
      
      A quick explanation to the existing functionality
      of allowTags and denyTags:
      
      * If parseFunc stumbles across a tag, which is NOT
        a typotag (tags.a for example), and NOT an external
        block, it will be checked if it is in "allowTags"
        or NOT in "denyTags", then it gets rendered, otherwise
        the tag including its contents is htmlspecialchar'ed.
      
      The tags are thus NOT removed, but instead hsced.
      
      In order to simplify the process, allowTags and denyTags
      can now be omitted, with the following result:
      
      If allowTags = a,b,em... ONLY these tags are allowed,
      and denyTags does not matter anymore already.
      
      allowTags can now be set to "*", thus denyTags can be
      used to mark explicitly use "denyTags".
      
      It now makes little sense to define allowTags AND
      den...
      4da2551c
  22. Jun 26, 2024
  23. Jun 21, 2024
  24. Jun 19, 2024
  25. Jun 14, 2024
  26. Jun 13, 2024
  27. Jun 11, 2024
  28. Jun 01, 2024
  29. May 31, 2024
  30. May 27, 2024
  31. May 24, 2024
    • Benni Mack's avatar
      [FEATURE] Group-based content fetching in Frontend · 31e37247
      Benni Mack authored
      This change adds a new RecordCollector which is similar
      to CONTENT cObject, except that it does not render the records
      directly, but instead creates instances of a generic Record
      object, so the Templating Engine can deal with the way of
      how the record should be rendered.
      
      Based on the Page Layout / Backend Layout, all registered
      colPos contents are fetched, and grouped, if the Backend Layout
      has an "identifier" set via a new PageContentFetchingProcessor
      ("page-content").
      
      The slide functionality can now be defined in the Page Layout as well
      (Backend Layout), with a Enum defining to Collect, CollectReverse
      and a simple Slide logic.
      
      This feature brings a clearer separation of fetching
      content from the database and the actual representation
      in the output (fluid) in place, allowing for further
      optimizations.
      
      In addition, one needs to write much less TypoScript
      to fetch all contents from a page.
      
      Next steps is then to enrich the records with their
      relations (see next feature), and to optimize the Fluid-based
      rendering for any kind of content.
      
      Resolves: #103894
      Releases: main
      Change-Id: I6a1a0efacefe8c83e86b9551b00199c93e284a28
      Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83638
      
      
      Reviewed-by: default avatarOliver Bartsch <bo@cedev.de>
      Tested-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
      Reviewed-by: default avatarBenni Mack <benni@typo3.org>
      Tested-by: default avatarOliver Bartsch <bo@cedev.de>
      Reviewed-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
      Tested-by: default avatarcore-ci <typo3@b13.com>
      Tested-by: default avatarBenni Mack <benni@typo3.org>
      31e37247
  32. May 21, 2024