# @craftercms/ice 中文文档

规范地址：https://npmcn.com/package/%40craftercms/ice/

版本：4\.3\.1
npm 元数据更新时间：2026-07-07T18:40:38.171Z
中文译文更新时间：2026-11-10T22:56:41.664Z
软件包许可：GNU LGPL 3\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40craftercms/ice
原文对照：https://npmcn.com/package/%40craftercms/ice/?lang=original
项目主页：https://github.com/craftercms/craftercms-sdk-js#readme
源码仓库：https://github.com/craftercms/craftercms-sdk-js

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：277 kB，52 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react ^18\.0\.0 \|\| ^19\.0\.0
- 首次发布：2020-02-27T12:32:55.334Z
- 最新版本发布：2026-07-07T18:40:37.979Z
- 近 30 天下载量：2532（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：34（近 12 个月 1 个）

## 中文简介

CRafter CMS 文本编辑库

## 安装

```sh
npm install @craftercms/ice
```

也可以使用：`pnpm add @craftercms/ice`、`yarn add @craftercms/ice`、`bun add @craftercms/ice`

## README

![npm (scoped)](https://img.shields.io/npm/v/@craftercms/ice?style=plastic)

# @ crapercms/ice (英语)

包含 JavaScript 在您的应用程序和网站上使用 Crafter CMS 的内文本编辑工具

**说明**: 本套件的所有方法都与 [内容实例](https://npmcn.com/package/%40craftercms/models/src/ContentInstance.ts) 作为数据结构,他们理解(模型参数)。 与 `parseDescriptor` 财务报告和审定财务报表 `preParseSearchResults` 从 `@craftercms/content` 获取此类数据结构.

## 使用量

所有 Crafter CMS 包都可以通过 npm 使用,也可以通过常规脚本导入在 plain html/javascript中使用.

### 通过 npm

-   `yarn add @craftercms/ice` 或者说 `npm install @craftercms/ice`
-   `import` 或者说 `require` 您想要的函数.

### Via html 脚本导入

-   下载捆绑并在您的页面中导入 .
-   捆绑声明一个名为全局变量 `craftercms`。 您可以在此根下访问所有 Frapercms 的软件包和函数.
-   这个 `ice` 软件包依赖于 rxjs, 在 rxj 之前确保导入 rxjs `ice` 剧本.

**提示**: 一旦导入脚本, 类型 `craftercms` 在浏览器的 dev 工具控制台上检查软件包

#### Vanilla html/js 实例

```html
<div id="myFeature"></div>
<script src="https://unpkg.com/rxjs"></script>
<script src="https://unpkg.com/@craftercms/utils"></script>
<script src="https://unpkg.com/@craftercms/classes"></script>
<script src="https://unpkg.com/@craftercms/content"></script>
<script src="https://unpkg.com/@craftercms/ice"></script>
<script>
 (function ({ content, ice }, { operators }) {

   content.getItem(
     '/site/website/index.xml',
     { baseUrl: 'http://localhost:8080', site: 'editorial' }
   ).pipe(
     operators.map(content.parseDescriptor)
   ).subscribe((model) => {
     const attrs = ice.getICEAttributes({ model, parentModelId: '/site/website/index.xml' });
     const elem = document.querySelector('#myFeature');
     Object.entries(attrs).forEach(([attr, value]) => {
       elem.setAttribute(attr, value);
     });
     Object.entries(model).forEach(([fieldId, value]) => {
       if (fieldId !== 'craftercms') {
         const el = document.createElement('div');
         el.innerText = `${fieldId}: ${value}`;
         elem.appendChild(el);
       }
     });
   });

 })(craftercms, rxjs);
</script>
```

## 软件包索引

以下示例假设使用方式为 npm 。 如果你在使用捆绑, 直接导入浏览器中的脚本, 这些功能将在全局变量下 名称 `craftercms.ice` (即说. `window.craftercms.ice`) (中文(简体) ).

### 获取代理

询问当前源服务器,以确定该站点/应用程序是否在 Crafter CMS 编写环境(Preview)中运行. 肯定的答复(`true`)表示是作者;假设您需要添加铅笔并导入其他作者工具. 假手段是送出,所有撰写工具都应被禁用.

#### 示例

```typescript
import { fetchIsAuthoring } from '@craftercms/ice';

fetchIsAuthoring().then((isAuthoring) => {
  console.log(`You're currently in ${isAuthoring ? 'authoring' : 'delivery'}.`);
});
```

### 获取 Ice 属性

3⁄4 ̄ ̧漯B.

#### 示例

```typescript
  import { from, forkJoin } from 'rxjs';
  import { map } from 'rxjs/operators';
  import { getICEAttributes, fetchIsAuthoring, repaintPencils } from '@craftercms/ice';
  import { getItem, parseDescriptor } from '@craftercms/content';

  forkJoin({
    isAuthoring: from(fetchIsAuthoring()),
    model: getItem('/site/website/index.xml', { site: 'editorial' }).pipe(map(parseDescriptor))
  }).subscribe(({ isAuthoring, model }) => {
  
    const page = document.querySelector('#main');
    if (page) {
      const homepageEditPencil = getICEAttributes({ model, isAuthoring });
      Object.entries(homepageEditPencil).forEach(([attr, value]) => {
        page.setAttribute(attr, value);
      });
      repaintPencils();
    }
  
  });
```

### 获得DropZone 属性

3⁄4 ̄ ̧漯B.

#### 示例

```typescript
  import { from, forkJoin } from 'rxjs';
  import { map } from 'rxjs/operators';
  import { getICEAttributes, getDropZoneAttributes, fetchIsAuthoring, repaintPencils } from '@craftercms/ice';
  import { getItem, parseDescriptor } from '@craftercms/content';

  forkJoin({
    isAuthoring: from(fetchIsAuthoring()),
    model: getItem('/site/website/index.xml', { site: 'editorial' }).pipe(map(parseDescriptor))
  }).subscribe(({ isAuthoring, model }) => {
  
    const features = document.querySelector('.features');
    if (features) {

      const homepageFeaturesDropZone = getDropZoneAttributes({ model, isAuthoring, zoneName: 'features_o' });
      Object.entries(homepageFeaturesDropZone).forEach(([attr, value]) => {
        features.setAttribute(attr, value);
      });

      const items = features.querySelectorAll('article');
      items.forEach((item) => {
        const pencil = getICEAttributes({ model, isAuthoring });
        Object.entries(pencil).forEach(([attr, value]) => {
          item.setAttribute(attr, value);
        });
      });
        
      repaintPencils();

    }

  });
```

### 添加授权支持

使用这种方法包含必要的脚本,以便在您的站点/应用程序上启用 Crafter CMS 编写支持(即铅笔,拖放等). 此函数不检查您是否正在编写或交付 。 在援引之前你应该检查一下.

#### 示例

```typescript
import React, { useEffect } from 'react';
import { isAuthoring } from '../utils';
import { addAuthoringSupport } from '@craftercms/ice';

function App() {
  useEffect(() => {
    if (isAuthoring()) {
      // This is a react example but you may use addAuthoringSupport outside of react
      addAuthoringSupport().then(() => {
        // Feel free to discard the promise if you don't need 
        console.log('Authoring tools have loaded and are ready to use.');
      });
    }
  }, []);
  return (
    {/* ... */}
  );
}
```

### 重新油漆 Pencils

重交所有铅笔

#### 示例

```typescript
import { repaintPencils } from '@craftercms/ice';

new Carousel({
  element: '#myElement',
  // ...other settings
  onSlideChange: () => {
    // Update pencils so current slide pencil is visible and prev slide is gone.
    repaintPencils();
  }
});
```

### 导航报告

向Crafter Studio报告导航情况.

在没有页面再装入时主要用于SPA,但页面上下文会发生变化.

### 示例

```typescript
import { reportNavigation } from '@craftercms/ice';

function DynamicRoute(props) {
  const { match, location } = props;
  let url = match.path.includes(':')
    ? match.path.substring(0, match.path.indexOf(':') -1)
    : match.url;
  useEffect(() => {
    reportNavigation(url);
  }, [url]);
  return (
    ...
  );
}
```

## @ crapercms/ice/ react

铅笔和弹出区的反应 要求16.8.0或以上反应(呼出). 类组件不可用,使用上述同包部分描述的平面方法.

### 用户

3⁄4 ̄ ̧漯B.

确保使用来自 `@craftercms/content` 这就是这些钩子所理解的结构.

#### 示例

```typescript
  import React, { useEffect, useState } from 'react';
  import { from, forkJoin } from 'rxjs';
  import { map } from 'rxjs/operators';
  import { fetchIsAuthoring } from '@craftercms/ice';
  import { useICE } from '@craftercms/ice/react';
  import { getItem, parseDescriptor } from '@craftercms/content';
  
  function App() {
    const [state, setState] = useState();
    useEffect(() => {
      forkJoin({
        isAuthoring: from(fetchIsAuthoring()),
        model: getItem('/site/website/index.xml', { site: 'editorial' }).pipe(map(parseDescriptor))
      }).subscribe(({ isAuthoring, model }) => {
        setState({ isAuthoring, model });
      });
    }, []);
    return (
      state ? <HomePage /> : 'Loading...'
    );
  }
  
  function HomePage(props) {
    const { isAuthoring, model } = props;
    const { props: pencil } = useICE({ isAuthoring, model });
    return  (
      <div {...pencil}>
        {/* ... */}
      </div>
    );
  }
  
```

### 使用 DropZone

3⁄4 ̄ ̧漯B.

确保使用来自 `@craftercms/content` 这就是这些钩子所理解的结构.

```typescript
  import React, { useEffect, useState } from 'react';
  import { from, forkJoin } from 'rxjs';
  import { map } from 'rxjs/operators';
  import { fetchIsAuthoring } from '@craftercms/ice';
  import { useICE, useDropZone } from '@craftercms/ice/react';
  import { getItem, parseDescriptor } from '@craftercms/content';
  
  function App() {
    const [state, setState] = useState();
    useEffect(() => {
      forkJoin({
        isAuthoring: from(fetchIsAuthoring()),
        model: getItem('/site/website/index.xml', { site: 'editorial' }).pipe(map(parseDescriptor))
      }).subscribe(({ isAuthoring, model }) => {
        setState({ isAuthoring, model });
      });
    }, []);
    return (
      state ? <HomePage /> : 'Loading...'
    );
  }
  
  function HomePage(props) {
    const { isAuthoring, model } = props;
    const { props: pencil } = useICE({ isAuthoring, model });
    const { props: dz } = useDropZone({ isAuthoring, model, fieldId: 'features_o' });
    return  (
      <div {...pencil}>
        <section className="features" {...dz}>
          {
            model.features_o.map((feature) => <Feature model={feature} isAuthoring={isAuthoring} />)
          }
        </section>
      </div>
    );
  }
  
  function Feature(props) {
    const { isAuthoring, model } = props;
    const { props: pencil } = useICE({ isAuthoring, model });
    return  (
      <article {...pencil}>
        <h2>{model.title_s}</h2>
        <p>{model.body_s}</p>
      </article>
    );
  }
```

## 常见问题

### @craftercms/ice 是什么？

CRafter CMS 文本编辑库

### 如何安装 @craftercms/ice？

在项目目录运行 npm install @craftercms/ice，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^18\.0\.0 \|\| ^19\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @craftercms/ice 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @craftercms/ice 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @craftercms/ice 可以商用吗？

@craftercms/ice 使用 GNU LGPL 3\.0 许可。声明的许可为 GNU LGPL 3\.0，请阅读许可原文确认使用条件。以上为概括，不构成法律意见，请以许可原文为准。

### @craftercms/ice 的下载量有多少？

根据 npm 官方下载统计，@craftercms/ice 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,532 次，日均约 84 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @craftercms/ice 还在维护吗？

最新版本 4\.3\.1 发布于 2026/07/08（4 个月前）；至今共发布 34 个版本，其中过去 12 个月发布了 1 个；首次发布于 2020/02/27。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

