Flutter内容管理系统插件utopia_cms的使用

Flutter内容管理系统插件utopia_cms的使用

Utopia CMS (Core)

Utopia CMS Core 包是一个用Flutter编写的可视化库,用于创建漂亮、动画效果、高性能且灵活的CMS面板,这些面板用于管理移动应用的数据库。

动机

在Flutter中创建CMS面板的成本可能比使用无代码/低代码解决方案要高。然而,我们认为这对于项目来说仍然是有益的,因为它确保了可维护性,并允许创建出色的UI,这是现有解决方案中经常缺乏的。这就是我们开发此低代码库以优化自定义面板创建过程的原因。

示例

这是一个简单的示例,它与GraphQL服务器集成,并创建一个包含一页和管理流程的完整的CMS布局。

class Example extends StatelessWidget {
  final String? pageId;
  final void Function(String pageId) onPageChanged;
  final GraphQLClient client;

  const Example({required this.pageId, required this.onPageChanged, required this.client});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CmsWidget(
        selectedPageId: MutableValue.delegate(() => pageId ?? 'users', onPageChanged),
        items: [
          CmsWidgetItem.page(
            id: 'products',
            icon: Icon(Icons.shopping_basket_outlined),
            title: Text('Products'),
            content: _buildProductsPage(),
          ),
        ],
      ),
    );
  }

  CmsTablePage _buildProductsPage() {
    return CmsTablePage(
      title: "Products",
      delegate: CmsHasura.delegate(
        client: client,
        table: Tables.products,
        fields: TableFields.products,
        archivedFilter: const CmsFilterNotEquals("archived", true),
      ),
      entries: [
        CmsTextEntry(key: "name", modifier: const CmsEntryModifier(sortable: true)),
        CmsTextEntry(key: "description", flex: 4),
      ],
    );
  }
}

CMS概述与基本功能

utopia_cms_core 库提供了以下功能,用于创建服务器层、响应式表格页面、编辑/创建流程和内部导航。它还支持与自定义页面的集成,并提供一组有用的组件来保持应用程序的主题一致性。

CmsWidget

包装整个应用程序并使用 CmsMenu 创建适当的分页行为。

CmsThemeData

修改小部件的样式,确定字体和颜色。

CmsTable

这是一个独立的小部件,用于基于表格的内容管理。默认情况下,它显示一个可排序和可筛选的表格,引入了25项无限滚动分页,创建编辑和创建子页面,并支持项目移除。数据由 CmsDelegate 提供,并由 CmsEntry 显示。请求可以通过 CmsFilterEntry 进行筛选。

CmsEntry

此接口处理数据的显示和管理。有一组预创建的基本数据类型的交互原语。

名称 描述
CmsTextEntry 处理通用字符串变量
CmsNumEntry 处理数字变量
CmsDropdownEntry 管理选项集和单选选择
CmsBoolEntry 处理布尔变量
CmsDateEntry 处理日期变量
CmsMediaEntry 处理文件(图像、视频、文档、未知)
CmsToManyDropdownEntry 多对多关系多选下拉菜单

你可以通过参考任何原始实现和 CmsEntry 来创建自定义条目。

CmsFilterEntry

此接口处理CmsTable字段的过滤。

名称 描述
CmsFilterSearchEntry 处理通用字符串全文搜索
CmsFilterDateEntry 处理日期范围

你可以通过参考任何原始实现和 CmsFilterEntry 来创建自定义过滤器条目。

CmsDelegate

这是处理 CmsTable 的主要接口。它本身不适合处理多对多关系。为了实现这一功能,请参阅 Relationships

该库提供预创建的委托:

名称 描述
utopia_cms_firebase Firebase委托集成
utopia_cms_graphql 通用GraphQL委托集成
utopia_cms_hasura Hasura委托集成

要创建自己的委托,请参考任何委托的实现和 CmsDelegate 接口。

关系

在系统中处理基于关系的条目稍微复杂一些。对于特定条目,你需要使用 CmsToManyDelegate,并向 Provider 可用的 CmsItemManagementBaseState 注册额外的回调。

final baseState = Provider.of<CmsItemManagementBaseState>(context);

baseState.addOnSavedCallback(
    (value) async {
        return delegate.update(...);
    }
);

该库提供了以下现有的关系解决方案:

现有的 CmsToManyDelegate 实现 来源
CmsHasuraOneToManyDelegate, CmsHasuraManyToManyDelegate utopia_cms_hasura

媒体

媒体如图像或视频由 CmsMediaDelegate 处理,它引入了上传和删除功能。

该库目前还没有为关系提供现有的通用解决方案,但这里有一个例子:

class FileDelegate implements CmsMediaDelegate {
  final CmsGraphQLService graphQLService;
  final GraphQLClient client;

  const FileDelegate(this.graphQLService, this.client);

  Future<({String downloadUrl, CmsFileRef ref})> upload(XFile file) async {
    final (uploadUrl, downloadUrl) = await _createAttachment(mimeType: file.mimeType!);
    await _upload(uploadUrl, file);
    return (downloadUrl: downloadUrl, ref: "XD");
  }

  Future<(String, String)> _createAttachment({required String mimeType}) async {
    final result = await graphQLService.mutate(
      client,
      name: 'createAttachment',
      arguments: {'data': {'contentType': mimeType}.toValueNodeUnsafe()},
      fields: {CmsGraphQLField('uploadUrl'), CmsGraphQLField('downloadUrl')},
    );
    result as Map<String, dynamic>;
    return (result['uploadUrl'] as String, result['downloadUrl'] as String);
  }

  Future<void> _upload(String url, XFile file) async {
    final webFile = await HttpRequest.request(file.path, responseType: 'blob');
    final request = await HttpRequest.request(url, method: 'PUT', mimeType: file.mimeType!, sendData: webFile.response);
    if(request.status != HttpStatus.ok) throw Exception("Failed to upload");
  }
}

更多关于Flutter内容管理系统插件utopia_cms的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter内容管理系统插件utopia_cms的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Utopia CMS 是一个用于 Flutter 的内容管理系统(CMS)插件,它可以帮助开发者快速构建和管理应用程序中的内容。Utopia CMS 提供了一套工具和组件,使得开发者可以轻松地集成内容管理功能到 Flutter 应用中。

以下是如何使用 Utopia CMS 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 utopia_cms 依赖。

dependencies:
  flutter:
    sdk: flutter
  utopia_cms: ^latest_version

请将 latest_version 替换为最新版本的 utopia_cms

2. 导入包

在你的 Dart 文件中导入 utopia_cms 包。

import 'package:utopia_cms/utopia_cms.dart';

3. 初始化 CMS

在你的 Flutter 应用中初始化 Utopia CMS

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Utopia CMS Demo',
      home: UtopiaCmsHome(),
    );
  }
}

4. 创建 CMS 页面

你可以创建一个简单的 CMS 页面来管理内容。

class UtopiaCmsHome extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Utopia CMS'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Welcome to Utopia CMS'),
            ElevatedButton(
              onPressed: () {
                // 导航到 CMS 管理页面
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => UtopiaCmsManagementPage(),
                  ),
                );
              },
              child: Text('Manage Content'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 管理内容

UtopiaCmsManagementPage 中,你可以使用 Utopia CMS 提供的组件来管理内容。

class UtopiaCmsManagementPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Content Management'),
      ),
      body: ListView(
        children: [
          ListTile(
            title: Text('Manage Posts'),
            onTap: () {
              // 导航到帖子管理页面
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => UtopiaCmsPostManagementPage(),
                ),
              );
            },
          ),
          ListTile(
            title: Text('Manage Users'),
            onTap: () {
              // 导航到用户管理页面
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => UtopiaCmsUserManagementPage(),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

6. 自定义内容管理页面

你可以根据需要自定义内容管理页面。例如,创建一个帖子管理页面:

class UtopiaCmsPostManagementPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Post Management'),
      ),
      body: ListView.builder(
        itemCount: 10, // 假设有10个帖子
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('Post $index'),
            subtitle: Text('This is a sample post'),
            onTap: () {
              // 导航到帖子编辑页面
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => UtopiaCmsPostEditPage(postId: index),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

7. 编辑内容

你可以创建一个页面来编辑帖子内容:

class UtopiaCmsPostEditPage extends StatelessWidget {
  final int postId;

  UtopiaCmsPostEditPage({required this.postId});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Post $postId'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(labelText: 'Title'),
            ),
            SizedBox(height: 16),
            TextField(
              decoration: InputDecoration(labelText: 'Content'),
              maxLines: 5,
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                // 保存帖子内容
                // 这里可以添加保存逻辑
              },
              child: Text('Save'),
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部