这是 Jinja2 教程的第 4 部分内蒙古板链式过滤机,我们将继续研究语言特性内蒙古板链式过滤机,特别是我们将讨论模板过滤器。我们将了解过滤器是什么以及如何在模板中使用它们。我还将向您展示如何编写自己的自定义过滤器。
Jinja2 过滤器概述让我们直接进入。 Jinja2 过滤器是我们用来转换变量中保存的数据的东西。|我们通过在变量后放置管道符号和过滤器名称来应用过滤器。
过滤器可以更改源数据的外观和格式,甚至可以生成从输入值派生的新数据。重要的是原始数据被转换的结果替换,这就是最终呈现的模板。
下面是一个示例,展示了一个简单的过滤器的作用:
模板:
First name: {{ first_name | capitalize }}数据:
first_name: przemek结果:
First name: Przemek我们将first_name变量传递给capitalize过滤器。正如过滤器的名称所暗示的那样,变量保存的字符串最终将大写。这正是我们所看到的。很酷,对吧内蒙古板链式过滤机?
将过滤器视为将 Jinja2 变量作为参数的函数可能会有所帮助,与标准 Python 函数的唯一区别是我们使用的语法。
Python 等价物capitalize看起来像这样:
def capitalize(word): return word.capitalize()first_name = "przemek"print("First name: {}".format(capitalize(first_name)))太好了,你说。但我怎么知道这capitalize是一个过滤器?它从哪里来的?
这里没有魔法。有人必须对所有这些过滤器进行编码,并让它们可供我们使用。Jinja2 带有许多有用的过滤器,capitalize就是其中之一。
所有内置过滤器都记录在 Jinja2 官方文档中。我在参考文献中包含了链接,在这篇文章的后面,我将展示一些在我看来更有用的过滤器示例。
多个参数我们不仅限于简单的过滤器,例如capitalize. 一些过滤器可以在括号中使用额外的参数。这些可以是关键字或位置参数。
下面是一个采用额外参数的过滤器示例。
模板:
ip name-server {{ name_servers | join(" ") }}数据:
name_servers: - 1.1.1.1 - 8.8.8.8 - 9.9.9.9 - 8.8.4.4结果:
ip name-server 1.1.1.1 8.8.8.8 9.9.9.9 8.8.4.4过滤器通过将列表的元素与空格作为分隔符粘合在一起来获取join存储的列表并创建一个字符串。name_servers分隔符是我们在括号中提供的参数,我们可以根据需要使用不同的参数。
您应该参考文档以了解哪些参数(如果有)可用于给定过滤器。大多数过滤器使用合理的默认值,并且不需要显式指定所有参数。
链接过滤器我们已经看到了基本的过滤器用法,但我们可以做得更多。我们可以将过滤器链接在一起。这意味着可以一次使用多个过滤器,每个过滤器用管道分隔|。
Jinja 从左到右应用链式过滤器。来自最左边过滤器的值被送入下一个过滤器,并重复该过程直到没有更多过滤器。只有最终结果才会出现在渲染模板中。
让我们看看它是如何工作的。
数据:
scraped_acl: - " 10 permit ip 10.0.0.0/24 10.1.0.0/24" - " 20 deny ip any any"模板
{{ scraped_acl | first | trim }}结果
10 permit ip 10.0.0.0/24 10.1.0.0/24我们传递了包含两个要first过滤的项目的列表。这从列表中返回了第一个元素,并将其交给trim过滤器删除了前导空格。
最终结果是 line 10 permit ip 10.0.0.0/24 10.1.0.0/24。
过滤器链接是一项强大的功能,它允许我们一次执行多个转换。另一种方法是存储中间结果,这会降低可读性并且不会那么优雅。
附加过滤器和自定义过滤器尽管它们很棒,但内置过滤器非常通用,许多用例需要更具体的过滤器。这就是为什么像 Ansible 或 Salt 这样的自动化框架提供了许多额外的过滤器来覆盖广泛的场景。
在这些框架中,您会发现过滤器可以转换 IP 对象、在 YAML/Json 中显示数据,甚至应用正则表达式,仅举几例。在参考资料中,您可以找到每个框架中可用过滤器的文档链接。
最后,您可以自己创建新的过滤器内蒙古板链式过滤机!Jinja2 提供了添加自定义过滤器的钩子。这些只是 Python 函数,因此如果您在编写 Python 函数之前也可以编写自己的过滤器!
上述自动化框架也支持自定义过滤器,编写它们的过程类似于 vanilla Jinja2。您再次需要编写 Python 函数,然后给定工具的文档将向您显示将模块注册为过滤器所需的步骤。
为什么要使用过滤器?没有工具能很好地解决所有问题。有些工具是寻找问题的解决方案。那么,为什么要使用 Jinja2 过滤器呢?
与大多数模板语言一样,Jinja 的创建考虑了 Web 内容。虽然数据以标准化格式存储在数据库中,但我们在向用户显示文档时经常需要对其进行转换。这就是像 Jinja 这样的语言及其过滤器可以随时随地修改数据的呈现方式,而无需触及后端。这就是过滤器的卖点。
下面是我个人的看法,为什么我认为 Jinja2 过滤器是该语言的一个很好的补充:
1.它们允许非程序员执行简单的数据转换。
这适用于普通过滤器以及自动化框架提供的额外过滤器。例如,网络工程师知道他们的 IP 地址,他们可能希望在没有任何编程知识的情况下在模板中对其进行操作。过滤器来拯救!
2. 你会得到可预测的结果。
如果你使用一般可用的过滤器,任何有一些 Jinja2 经验的人都会知道他们在做什么。这使人们在查看其他人编写的模板时能够加快速度。
3. 过滤器维护良好且经过测试。
内置过滤器以及自动化框架提供的过滤器被很多人广泛使用。这使您对他们给出正确的结果并且没有很多错误充满信心。
4. 最好的代码是完全没有代码。
在您向程序添加数据转换操作或创建新过滤器的那一刻,您将永远对代码负责。任何错误、功能请求和测试都将在解决方案的整个生命周期内出现。在学习时写尽可能多的东西,但尽可能在生产中使用已经可用的解决方案。
什么时候不使用过滤器?过滤器非常强大,可以为我们节省大量时间。但权力越大,责任越大。过度使用过滤器,您最终会得到难以理解和维护的模板。
你知道那些没有人,包括你自己,能在几个月后理解的聪明的一班人吗?通过链接大量过滤器很容易进入这些情况,尤其是那些接受多个参数的过滤器。
我使用以下启发式方法来帮助我确定我所做的是否太复杂:
我写的东西是我理解的极限吗?我是不是觉得我刚刚写的很聪明?我是否以一种起初看起来并不明显的方式使用了许多链式过滤器?如果您对上述至少一项的回答是肯定的,那么您可能正在处理“为自己好而太聪明”的情况。您的用例可能没有更简单的解决方案,但您可能需要进行重构。如果您不确定是否是这种情况,最好询问您的同事或咨询社区。
为了向您展示事情会变得多么糟糕,这是我几年前写的 Jinja2 行的示例。这些使用 Ansible 提供的过滤器,它变得非常复杂,以至于我不得不定义中间变量。
看看它并尝试弄清楚它做了什么,更重要的是,它是如何做到的。
模板,为了简洁而删减:
{% for p in ibgp %}{% set jq = "[?name=='" + p.port + "'].{ myip: ip, peer: peer }" %}{% set el = ports | json_query(jq) %}{% set peer_ip = hostvars[el.0.peer] | json_query('ports[*].ip') | ipaddr(el.0.myip) %}...{% endfor %}与模板一起使用的示例数据:
ibgp: - { port: Ethernet1 } - { port: Ethernet2 }..ports: - { name: Ethernet1, ip: "10.0.12.1/24", speed: 1000full, desc: "vEOS-02这里有很多东西要解压。在第一行中,我将查询字符串分配给变量作为字符转义问题的解决方法。在第二行中,我使用json_query来自第一行变量的参数应用过滤器,结果存储在另一个辅助变量中。最后,在第三行中,我应用了两个链式过滤器json_query和ipaddr.
这三行的最终结果应该是在给定接口上找到的 BGP 对等体的 IP 地址。
我相信你会同意我的看法,这很糟糕。这个解决方案在我之前提到的启发式方法旁边是否有任何标记?是的!他们三个!这是重构的主要候选者。
在这种情况下,我们通常可以做两件事:
在调用渲染的上层对数据进行预处理,例如 Python、Ansible 等。编写自定义过滤器。修改数据模型,看看是否可以简化。在这种情况下,我选择了选项 2,我编写了自己的过滤器,幸运的是,这是我们列表中的下一个主题。
编写自己的过滤器正如我已经提到的,要编写自定义过滤器,您需要亲自动手并编写一些 Python 代码。不过不要害怕!如果你曾经写过一个带参数的函数,那么你已经得到了它所需要的一切。没错,我们不需要做太花哨的事情,任何普通的 Python 函数都可以成为过滤器。它只需要至少接受一个参数并且它必须返回一些东西。
这是我们将在 Jinja2 引擎中注册为过滤器的函数示例:
# hash_filter.pyimport hashlibdef j2_hash_filter(value, hash_type="sha1"): """ Example filter providing custom Jinja2 filter - hash Hash type defaults to 'sha1' if one is not specified :param value: value to be hashed :param hash_type: valid hash type :return: computed hash as a hexadecimal string """ hash_func = getattr(hashlib, hash_type, None) if hash_func: computed_hash = hash_func(value.encode("utf-8")).hexdigest() else: raise AttributeError( "No hashing function named {hname}".format(hname=hash_type) ) return computed_hash在 Python 中,这是我们告诉 Jinja2 过滤器的方式:
# hash_filter_test.pyimport jinja2from hash_filter import j2_hash_filterenv = jinja2.Environment()env.filters["hash"] = j2_hash_filtertmpl_string = """MD5 hash of '$3cr3tP44$$': {{ '$3cr3tP44$$' | hash('md5') }}"""tmpl = env.from_string(tmpl_string)print(tmpl.render())渲染结果:
MD5 hash of '$3cr3tP44$$': ec362248c05ae421533dd86d86b6e5ff看那个!我们自己的过滤器!它的外观和感觉就像内置的 Jinja 过滤器,对吧?
它有什么作用?它公开了 Pythonhashlib库中的散列函数,以允许在 Jinja2 模板中直接使用散列。如果你问我,那就太好了。
简而言之,以下是创建自定义过滤器所需的步骤:
创建一个至少接受一个参数并返回一个值的函数。第一个参数始终是|符号前面的 Jinja 变量。括号中提供了后续参数(...)。在 Jinja2 环境中注册函数。在 Python 中,将您的函数插入到filters字典中,这是Environment对象的一个属性。键名是您希望调用过滤器的名称,在这里hash,值是您的功能。您现在可以像使用任何其他 Jinja 过滤器一样使用您的过滤器。使用 Ansible 自定义过滤器修复“太聪明”的解决方案我们知道如何编写自定义过滤器,所以现在我可以向您展示我是如何用聪明的技巧替换模板的一部分的。
这是我完全荣耀的自定义过滤器:
# get_peer_info.pyimport ipaddressdef get_peer_info(our_port_info, hostvars): peer_info = {"name": our_port_info["peer"]} our_net = ipaddress.IPv4Interface(our_port_info["ip"]).network peer_vars = hostvars[peer_info["name"]] for _, peer_port_info in peer_vars["ports"].items(): if not peer_port_info["ip"]: continue peer_net_obj = ipaddress.IPv4Interface(peer_port_info["ip"]) if our_net == peer_net_obj.network: peer_info["ip"] = peer_net_obj.ip break return peer_infoclass FilterModule(object): def filters(self): return { 'get_peer_info': get_peer_info }第一部分是你以前见过的,它是一个 Python 函数,它接受两个参数并返回一个值。当然,它比“聪明的”三行更长,但它的可读性要强得多。
这里有更多的结构,变量有有意义的名字,我可以马上知道它在做什么。更重要的是,我知道它是如何做到的,过程被分解成许多易于遵循的单独步骤。
Ansible 中的自定义过滤器我的解决方案的第二部分与普通 Python 示例有点不同:
class FilterModule(object): def filters(self): return { 'get_peer_info': get_peer_info }这就是你告诉 Ansible 你想get_peer_info注册为 Jinja2 过滤器的方式。
您FilterModule使用一种名为 的方法创建名为的类filters。此方法必须返回带有过滤器的字典。字典中的键是过滤器的名称,值是函数。我说的是过滤器而不是过滤器,因为您可以在一个文件中注册多个过滤器。如果您愿意,您可以选择为每个文件设置一个过滤器。
完成所有操作后,您需要将 Python 模块放入filter_plugins目录中,该目录应位于存储库的根目录中。有了这些,您就可以在 Ansible Playbooks 和 Jinja2 模板中使用您的过滤器。
您可以在下面看到我的剧本与模块相关的目录deploy_base.yml结构get_peer_info.py。
.├── ansible.cfg├── deploy_base.yml├── filter_plugins│ └── get_peer_info.py├── group_vars ...├── hosts├── host_vars ...└── roles └── baseJinja2 过滤器 - 使用示例所有 Jinja2 过滤器都在官方文档中有详细记录,但我觉得其中一些可以使用更多示例。您将在下面找到我的主观选择以及一些评论和解释。
批batch(value, linecount, fill_with=None)- 允许您将列表元素分组到多个存储桶中,每个存储桶最多包含n 个元素,其中n是我们指定的数字。可选地,我们还可以要求batch使用默认条目填充存储桶,以使所有存储桶的长度恰好为 n。结果是列表列表。
我发现将项目分成固定大小的组很方便。
模板:
{% for i in sflow_boxes|batch(2) %}Sflow group{{ loop.index }}: {{ i | join(', ') }}{% endfor %}数据:
sflow_boxes: - 10.180.0.1 - 10.180.0.2 - 10.180.0.3 - 10.180.0.4 - 10.180.0.5结果:
center(value, width=80)- 通过添加空格填充在给定宽度的字段中居中值。在向报告添加格式时很方便。
模板:
{{ '-- Discovered hosts --' | center }}{{ hosts | join('\n') }}数据:
hosts: - 10.160.0.7 - 10.160.0.9 - 10.160.0.3结果:
-- Discovered hosts -- 10.160.0.710.160.0.910.160.0.15默认default(value, default_value='', boolean=False)- 如果未指定传递的变量,则返回默认值。用于防范未定义的变量。也可以用于我们想要设置为默认值的可选属性。
在下面的示例中,我们将接口放置在其配置的 vlan 中,或者如果未指定 vlan,我们默认将它们分配给 vlan 10。
模板:
{% for intf in interfaces %}interface {{ intf.name }} switchport mode access switchport access vlan {{ intf.vlan | default('10') }}{% endfor %}数据:
interfaces: - name: Ethernet1 vlan: 50 - name: Ethernet2 vlan: 50 - name: Ethernet3 - name: Ethernet4结果:
dictsort(value, case_sensitive=False, by='key', reverse=False)- 允许我们对字典进行排序,因为它们在 Python 中默认不排序。默认情况下按键排序,但您可以使用属性请求按值by='value'排序。
在下面的示例中,我们按名称(dict 键)对前缀列表进行排序:
模板:
{% for pl_name, pl_lines in prefix_lists | dictsort %}ip prefix list {{ pl_name }} {{ pl_lines | join('\n') }}{% endfor %}数据:
prefix_lists: pl-ntt-out: - permit 10.0.0.0/23 pl-zayo-out: - permit 10.0.1.0/24 pl-cogent-out: - permit 10.0.0.0/24结果:
如果加上dictsort(by='value', reverse=true)
在这里,我们按优先级(dict值)排序一些对等列表,更高的值更受欢迎,因此使用reverse=true:
模板:
BGP peers by priority{% for peer, priority in peer_priority | dictsort(by='value', reverse=true) %}Peer: {{ peer }}; priority: {{ priority }}{% endfor %}数据:
peer_priority: ntt: 200 zayo: 300 cogent: 100结果:
BGP peers by priorityPeer: zayo; priority: 300Peer: ntt; priority: 200Peer: cogent; priority: 100漂浮float(value, default=0.0)- 将值转换为浮点数。API 响应中的数值有时以字符串形式出现。通过float我们可以确保在进行比较之前转换字符串。
这是一个使用float.
模板:
{% if eos_ver | float >= 4.22 %}Detected EOS ver {{ eos_ver }}, using new command syntax.{% else %}Detected EOS ver {{ eos_ver }}, using old command syntax.{% endif %}数据:
eos_ver: "4.10"结果
Detected EOS ver 4.10, using old command syntax.通过...分组groupby(value, attribute)- 用于根据属性之一对对象进行分组。您可以选择使用点表示法按嵌套属性进行分组。此过滤器可用于基于特征值的报告或为仅适用于对象子集的操作选择项目。
在下面的示例中,我们根据分配给它们的 vlan 对接口进行分组:
模板:
{% for vid, members in interfaces | groupby(attribute='vlan') %}Interfaces in vlan {{ vid }}: {{ members | map(attribute='name') | join(', ') }}{% endfor %}数据:
interfaces: - name: Ethernet1 vlan: 50 - name: Ethernet2 vlan: 50 - name: Ethernet3 vlan: 50 - name: Ethernet4 vlan: 60结果:
int(value, default=0, base=10)- 与浮点数相同,但在这里我们将值转换为整数。也可用于将其他基数转换为十进制基数:
下面的示例显示了十六进制到十进制的转换。
模板:
LLDP Ethertypehex: {{ lldp_ethertype }} dec: {{ lldp_ethertype | int(base=16) }}数据:
lldp_ethertype: 88CC结果:
LLDP Ethertypehex: 88CC dec: 35020加入join(value, d='', attribute=None)- 非常非常有用的过滤器。获取序列的元素并将连接的元素作为字符串返回。
对于只想显示项目而不进行任何操作的情况,它可以代替for循环。在这些情况下,我发现join版本更具可读性。
模板:
ip name-server {{ name_servers | join(" ") }}数据:
name_servers: - 1.1.1.1 - 8.8.8.8 - 9.9.9.9 - 8.8.4.4结果:
ip name-server 1.1.1.1 8.8.8.8 9.9.9.9 8.8.4.4地图map(*args, **kwargs)- 可用于查找属性或对序列中的所有对象应用过滤器。
例如,如果您想跨设备名称规范字母大小写,您可以一次性应用过滤器。
模板:
Name-normalized device list:{{ devices | map('lower') | join('\n') }}数据:
devices: - Core-rtr-warsaw-01 - DIST-Rtr-Prague-01 - iNET-rtR-berlin-01结果:
Name-normalized device list:core-rtr-warsaw-01dist-rtr-prague-01Inet-rtr-berlin-01就我个人而言,我发现它对于跨大量对象检索属性及其值最有用。这里我们只对name属性的值感兴趣:
模板:
Interfaces found:{{ interfaces | map(attribute='name') | join('\n') }}数据:
interfaces: - name: Ethernet1 mode: switched - name: Ethernet2 mode: switched - name: Ethernet3 mode: routed - name: Ethernet4 mode: switched结果:
Interfaces found:Ethernet1Ethernet2Ethernet3Ethernet4拒绝reject(*args, **kwargs)- 通过应用 Jinja2 测试并拒绝测试成功的对象来过滤项目序列。如果测试结果为 ,则该项目将从最终列表中删除true。
在这里,我们只想显示公共 BGP AS 编号。
模板:
Public BGP AS numbers:{% for as_no in as_numbers| reject('gt', 64495) %}{{ as_no }}{% endfor %}数据:
as_numbers: - 1794 - 28910 - 65203 - 64981 - 65099结果:
Public BGP AS numbers:179428910拒绝属性rejectattr(*args, **kwargs)- 与reject过滤器相同,但测试应用于对象的选定属性。
如果您选择的测试需要参数,请在测试名称之后提供它们,用逗号分隔。
在此示例中,我们希望通过将 test 应用于“mode”属性来从列表中删除“switched”接口。
模板:
Routed interfaces:{% for intf in interfaces | rejectattr('mode', 'eq', 'switched') %}{{ intf.name }}{% endfor %}数据:
interfaces: - name: Ethernet1 mode: switched - name: Ethernet2 mode: switched - name: Ethernet3 mode: routed - name: Ethernet4 mode: switched结果:
Routed interfaces:Ethernet3选择select(*args, **kwargs)- 通过仅保留通过 Jinja2 测试的元素来过滤序列。这个过滤器是相反的reject。您可以使用其中任何一种,具体取决于在给定场景中感觉更自然的情况。
与此类似,reject还有一个selectattr过滤器,其工作原理与每个对象的属性相同,select但适用于每个对象的属性。
下面我们要报告在我们的设备上找到的私有 BGP AS 编号。
模板:
Private BGP AS numbers:{% for as_no in as_numbers| select('gt', 64495) %}{{ as_no }}{% endfor %}数据:
as_numbers: - 1794 - 28910 - 65203 - 64981 - 65099结果:
Private BGP AS numbers:652036498165099Tojsontojson(value, indent=None)- 以 JSON 格式转储数据结构。当需要 JSON 的应用程序使用呈现的模板时很有用。也可以用作pprint美化变量调试输出的替代方法。
模板:
{{ interfaces | tojson(indent=2) }}数据:
interfaces: - name: Ethernet1 vlan: 50 - name: Ethernet2 vlan: 50 - name: Ethernet3 vlan: 50 - name: Ethernet4 vlan: 60结果:
[ { "name": "Ethernet1", "vlan": 50 }, { "name": "Ethernet2", "vlan": 50 }, { "name": "Ethernet3", "vlan": 50 }, { "name": "Ethernet4", "vlan": 60 }]独特unique(value, case_sensitive=False, attribute=None)- 返回给定集合中唯一值的列表。与过滤器很好地配对,map用于查找用于给定属性的一组值。
在这里,我们正在查找我们跨接口使用的访问 VLAN。
模板:
Access vlans in use: {{ interfaces | map(attribute='vlan') | unique | join(', ') }}数据:
interfaces: - name: Ethernet1 vlan: 50 - name: Ethernet2 vlan: 50 - name: Ethernet3 vlan: 50 - name: Ethernet4 vlan: 60结果:
Access vlans in use: 50, 60结论有了这个相当长的示例列表,我们到了教程的这一部分。Jinja2 过滤器可以成为一个非常强大的工具,我希望我的解释能帮助你看到它们的潜力。
您确实需要记住明智地使用它们,如果它开始看起来笨拙并且感觉不对,请查看替代方案。看看您是否可以将复杂性移到模板之外,修改您的数据模型,或者如果这不可能,请编写您自己的过滤器。
这都是我的。一如既往,期待再次见到您,更多 Jinja2 帖子即将发布!
参考Jinja2 内置过滤器,官方文档:https ://jinja.palletsprojects.com/en/2.11.x/templates/#builtin-filtersJinja2 自定义过滤器,官方文档:https ://jinja.palletsprojects.com/en/2.11.x/api/#custom-filtersAnsible 官方文档中提供的所有过滤器:https ://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.htmlSalt,官方文档中提供的所有过滤器:https ://docs.saltstack.com/en/latest/topics/jinja/index.html#filters包含这篇文章资源的 GitHub 存储库。可在:https ://github.com/progala/ttl255.com/tree/master/jinja2/jinja-tutorial-p4-template-filters凡本网注明“来源:砂石装备网”的所有作品,版权均属于砂石装备网,转载请注明。
凡注明为其它来源的信息,均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点及对其真实性负责。
如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们。
2025长沙国际工程机械展览会东南亚分展 2025 SOUTHEAST ASIA SUB-EXHIBITION OF CHANGSHA INTERNATIONAL CONSTRUCTION EQUIPMENT EXHIBITION 2025年9月3-5日(三天) 地点:马来西亚·吉隆坡实达城会展中心(SCCC...
2025-07-03 16:25:30
核心摘要:2025年5月18日,为期四天的第四届长沙国际工程机械展览会(以下简称“2025CICEE”)在长沙国际会展中心正式落下帷幕。本届展会 2025年5月18日,为期四天的第四届长沙国际工程机械展览会(以下简称“2025CICEE”)在长沙国际会展中心正式落下帷幕。本届展会以"高端化、智能化、...
2025-05-19 11:21:21
2025年5月15日上午9时40分,第四届长沙国际工程机械展览会在长沙国际会展中心隆重开幕。本届展会规模达30万平方米,全球1806家参展企业齐聚一堂,集中展示工程机械领域的最新技术与产品。1000余名全球行业领袖、院士专家、企业代表及国际采购商共同参会,见证这一国际工程机械领域的年度盛事。...
2025-05-16 08:31:29
日立建机参展的首台设备——ZX900LCH-6A矿山液压挖掘机。抵达长沙国际会展中心的卡特彼勒挖掘机。红网时刻新闻5月8日讯(记者 彭超)第四届长沙国际工程机械展将于5月15日开幕。还有一周的时间,国内外品牌相继进驻场馆布展。5月8日,日本日立建机、美国卡特彼勒两家全球工程机械50强企业的参展设备进驻长沙国际会展中心,...
2025-05-10 11:48:38
4月30日,湖南省政府新闻办举办新闻发布会,宣布第四届长沙国际工程机械展览会将于5月15日至18日启幕。当天,装载三一集团蓝色电动装载机的运输车辆驶入长沙国际会展中心,这也是第二家正式布展企业。据悉,三一集团将携旗下18个事业部和子公司、72件套设备(含58台主机)震撼登场,以10089平米的超大展位,全面展现三一的高...
2025-05-06 20:27:36
2025年4月30日,湖南省新闻办公室召开新闻发布会,宣布第四届长沙国际工程机械展览会定于5月15日至18日在长沙国际会展中心、长沙国际会议中心举办。长沙市人民政府副市长康镇麟出席发布会并介绍展会筹备情况:本届展览会以高端化、智能化、绿色化新一代工程机械、应急装备、矿山装备、农业机械为主题,预计吸引全球1650家参展企...
2025-05-06 20:27:07
5月,世界的目光将聚焦长沙。第四届长沙国际工程机械展将于5月15日至18日在长沙国际会展中心、长沙国际会议中心举行。4月29日,随着“全球工程机械制造商50强”中联重科的首批百吨设备进场,展会进入布展时间。上午9时30分,装载着中联重科工程机械零部件的平板车缓缓驶入长沙国际会展中心,荧光绿的漆面在阳光下格外显眼。这些设...
2025-04-30 09:19:07
当全球工程机械产业的聚光灯再次投向湘江之畔,2025CICEE《高端化、智能化、绿色化——新一代工程机械、应急装备、矿山装备、农业机械》电子会刊第二期正式发布。继首期会刊创下超192万次阅读的行业纪录后,本期会刊汇聚183家全球领军企业,以尖端技术产品和创新解决方案,续写“工程机械之都”的传奇篇章。01硬核生态:解码产...
2025-04-30 09:15:38
5月15日,2025长沙国际工程机械展览会(2025 CICEE)即将在长沙国际会展中心盛大开幕,届时,来自全球60多个国家和地区的超1600家参展商,将在30万平方米的展区内陈列超2万件展品,涵盖工程机械全领域前沿技术和产品。目前,众多展商已蓄势待发,期待在这个推动全球工程机械行业交流与合作的超级平台上一展风采。...
2025-04-17 08:31:38
在璀璨初夏的五月天,2025长沙国际工程机械展览会将于5月15日至18日在长沙国际会展中心华丽启幕。作为一颗迅速崛起的璀璨新星于世界工程机械展会之林,长沙展在规模之宏大、观众之众多、世界50强企业参展数量之多及影响力之广上,已可与全球三大工程机械展并驾齐驱,共绘辉煌。展会前夕,我们有幸专访了合肥长源液压股份有限公司的...
2025-04-17 08:30:36
主营:破碎机
主营:破碎机
主营:破碎机
主营:破碎机
主营:破碎机
主营:破碎机、制砂楼
主营:破碎机
主营:破碎机
主营:筛网、筛机配件
主营:振动电机
主营:破碎机
主营:制砂机、筛分设备