sitegeist/criticalmass

该包已被弃用且不再维护。作者建议使用punktde/archivist包代替。

在Neos中处理大量节点

安装数量: 4,768

依赖项: 0

建议者: 0

安全: 0

星标: 10

关注者: 5

分支: 1

公开问题: 0

类型:neos-package

v3.0.1 2018-04-27 10:06 UTC

README

管理大量节点的工具

自动创建节点层次结构

在Neos中,处理单个父节点下的大量文档有时很困难。在这种情况下,编辑很难再次找到特定的文档。此外,如果单个级别上的节点太多,当前导航组件的性能和可用性将受到影响。

为了克服这一点,我们建议使用集合节点的层次结构来创建适合当前项目的节点结构,并帮助编辑找到文档。这个解决方案的额外好处是,在文档-URL中代表该结构,这大大减少了URL冲突的可能性。

由于创建这样的节点层次结构是一项重复性任务,我们提供了这个包来自动化这项任务。

一个常见的用例是自动创建用于年份和月份的新闻集合节点,并将任何新闻节点移动到匹配的集合节点。

从CSV文件导入节点

将数据从表格结构导入neos通常需要实现自定义导入控制器,这是一个反复出现的要求。这个包允许将导入配置为节点或甚至节点层次结构。

注意:导入与自动节点层次结构创建一起工作。因此,如果您想导入到结构中,可以配置这两个选项。

将节点导出到CSV文件

对于将节点导出到表格结构,该包允许配置查询节点的表达式和导入表格每个列的表达式。

作者和赞助商

本包的开发和公共发布得到了我们的雇主http://www.sitegeist.de的慷慨赞助。

用法

Sitegeist:
  CriticalMass:
  
    # 
    # Automatic hierarchy creation
    # 
    automaticNodeHierarchy:
    
      # The configuration for the node type Sitegeist.CriticalMass:ExampleNode     
      'Sitegeist.CriticalMass:ExampleNode':

        # optional: Eel-values that are evaluates first and afterwards are available in the context 
        # of the eel expressions below. During evaluation the `site`, `documentNode` and `node` values are present.
        context: 
          year: "${q(node).property('startDate') ? Date.year(q(node).property('startDate')) : 'no-year'}"
          month: "${q(node).property('startDate') ? Date.month(q(node).property('startDate')) : 'no-month'}"

        # Detect the root-collection node that will contain the automatically created node hierarchy
        root: "${q(node).parents().filter('[instanceof Sitegeist.CriticalMass:ExampleNodeCollection]').slice(-1, 1).get(0)}"
        
        # optional: Automatically publish the created document hierarchy
        autoPublishPath: true

        # optional: Decide wether a node shall be handled or not
        condition: "${q(node).property('startDate') ? true : false}"
        
        # optional: The sorting of the nodes inside the target hierarchy
        sortBy: '${q(a).property("title") < q(b).property("title")}'

        # Define the levels of the node hierarchy that are created beneath the root node
        path:
       
          # level 1 year
          -
            # the type of the hierarchy-node  
            type: 'Sitegeist.CriticalMass:ExampleNodeCollection'
            
            # eel-expression to find existing collection nodes
            # the context contains the parent node as `parent` in addition to the default context values
            node: "${q(parent).children('[uriPathSegment = '\' + year + ' '\]').get(0)}"
            
            # optional: the sorting of the nodes on this level
            # the eel expression gets two nodes `a` and `b` in the context
            sortBy: '${q(a).property("title") < q(b).property("title")}'
             
            # properties that are applied only on node creation and can be edited afterwards
            properties:
              title: "${year}"
              uriPathSegment: "${year}"
          
          # level 2 month
          -
            # the type and nodename of the hierarchy-node  
            type: 'Sitegeist.CriticalMass:ExampleNodeCollection'
            # eel-expression to find existing collection nodes
            # the context contains the parent node as `parent` in addition to the default context values
            node: "${q(parent).children('[uriPathSegment = '\' + month + ' '\]').get(0)}"
            
            # optional: the sorting of the nodes on this level
            # the eel expression gets two nodes `a` and `b` in the context
            sortBy: '${q(a).property("title") < q(b).property("title")}'
             
            # properties that are applied only on node creation and can be edited afterwards
            properties:
              title: "${month}"
              uriPathSegment: "${month}"
    
    #
    # Node-import
    #
    import:
    
      # A single import preset for Sitegeist.CriticalMass:ExampleNode
      # 
      # !!! All expressions in here are evaluated with the `site` and the current `row` in the context.
      example-import:
      
        # optional: Description for the preset
        description: "Example-import description"
        
        # optional Eel-values that are evaluates first and afterwards are available in the context 
        context: 
          base: "${q(site).find('[instanceof Sitegeist.CriticalMass:ExampleCollection]').get(0)}"
        
        # optional: Configuration for importing previously imported nodes
        update: 
          # Expression that returns the node that shall be updated 
          node: "${q(base).find('[instanceof Sitegeist.CriticalMass:ExampleNode][importIdentifier=\"' +  row['ID'] + '\"]').get(0)}"

        # optional: Configuration for creating new nodes if no update was configured or no preexisting node is found
        create:
          # optional: skip import under certain conditions
          condition: "${row['ID'] ? true : false}"
          # Expression that returns the node that shall be updated 
          parentNode: "${base}"   
          # The type of the node that shall be created
          type: 'Sitegeist.CriticalMass:ExampleNode'
          # optional:  The properties that are set once for new imported nodes  
          properties:
            'importIdentifier': "${row['ID']}"

        # The properties that are updated during import AND update
        properties:
          'title': "${row['Title']}"
          'subtitle': "${row['Subtitle']}"
          'description': "${row['Description']}"
          'date': "${Date.parse(row['Date'], 'y-m-d')}"

        # optional: Import data into descendent-nodes
        #
        # !!! The expressions in here have the imported or updated node in the context as `ancestor`
        #
        # All the configuration from the main level can be used in here aswell. Descendent-nodes can
        # even have their own descendent nodes.
        descendants:
          image:
            update:
              node: "${q(ancestor).children('images').children().get(0)}"
            create:
              condition: "${row['Image'] ? true : false}"
              parentNode: "${q(ancestor).children('images').get(0)}"
              nodeType: 'Sitegeist.CriticalMass:ExampleImage'
            properties:
              'title': "${row['Title']}"
              'image': "${row['Image']}"
              
    #
    # Node-export
    #
    export:
      
      # A single export preset for Sitegeist.CriticalMass:ExampleNode
      # 
      # !!! All expressions in here are evaluated with the `site` and the current `row` in the context.
      example-export:
      
        # optional: Description for the preset
        description: "Example-export description"

        # Expression that returns the nodes that shall be exported 
        nodes: "${q(site).find('[instanceof Sitegeist.CriticalMass:ExampleNode]').get()}"
        
        # The properties that are exported
        #
        # Each configuration key in here is evaluated as en expression with 'site' and 'node' in the context.
        properties:
          'ID': "${q(node).property('importIdentifier')}"
          'Title': "${q(node).property('title')}"
          'Subtitle': "${q(node).property('subtitle')}"
          'Date': "${Date.format(q(node).property('date'), 'y-m-d')}"
          'Image': "${q(node).children('images').children().first().property('image')}"

命令

  • ./flow csv:showpresets - 列出定义的导入和导出预设
  • ./flow csv:import <preset> <file> - 从csv文件导入或更新节点
  • ./flow csv:export <preset> <file> - 将节点导出到csv文件

导入和导出命令期望csv文件的第一行包含字段名。

导入和导出命令有一个可选参数--site-node,可以用来指定导入的站点。如果没有提供此参数,则使用当前Neos设置的默认值。

限制

目前已知以下问题和副作用

  1. 目前无法通知导航组件进行所需的重新加载。因此,在节点被移动到幕后之后,导航组件将保持显示该节点在当前位置,直到下一次重新加载。
  2. 自动创建的节点位于用户工作区,并且仍需发布。如果您想避免这种情况,请使用选项 autoPublishPath

安装

Sitegeist.CriticalMass 通过 packagist 提供。只需将 "sitegeist/criticalmass" : "~1.0" 添加到 composer.json 的 require-dev 部分,或者运行 composer require --dev sitegeist/criticalmass。我们使用语义版本控制,因此每次重大更改都会增加主版本号。

许可证

请参阅 LICENSE 文件