Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the code generation method of golang standard library template

2025-02-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "what is the code generation method of golang standard library template", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Next, let the editor take you to learn "what is the code generation method of the golang standard library template?"

Curd-gen project

The curd-gen project was originally created as a tool for the illuminant project to generate the basic code in the front-end addition, deletion, modification and search page.

Recently, with the upgrade of antd Pro v5, the project was upgraded, and now all the ts code is generated. The automatically generated code for this project is based on golang's standard library template, so this blog is also a summary of the use of template libraries.

Automatically generated configuration

The automatic code generation of the curd-gen project consists of three main parts:

Type definition: each type used for API requests and page display

API requests: graphql request statements and functions

Pages: list pages, new pages and editing pages. Add and edit by popping up the modal box.

According to the content to be generated, a json format file is defined as the basis for code generation. The description of the json file is at: https://gitee.com/wangyubin/curd-gen#curdjson

Generate type definition

Type is the basis of API request and page display, and the general development process starts the development of API and page after defining the type according to the business.

Automatically generating type definitions is to generate type definitions of ts based on the list of fields in the json file. The template is defined as follows:

Const TypeDTmpl = `/ @ ts-ignore/* eslint-disable * / declare namespace API {type {{.Model.Name}} Item = {{- if .IsRequired}} {{- if. IsRequired}: {{. ConvertTypeForTs}; {{- else} {{.Name}}: {{ConvertTypeForts}} {{- end}} {{- / * end for if .IsRequired * /}} {{- end}} {{- end}} {{- end}} {- / * end for with .Model.Fields * /}}; type {{.Model.Name}} ListResult = CommonResponse & {data: {Model.GraphqlName}: {{.Model.Name}} Item [] {{.Model.GraphqlName}} _ aggregate: {aggregate: {count: number;}; type Create {{.Model.Name}} Result = CommonResponse & {data: {insert_ {{.Model.GraphqlName}}: {Model.GraphqlName};};} Type Update {{Model.Name}} Result = CommonResponse & {data: {update_ {{Model.GraphqlName}} _ by_pk: {id: string;};}; type Delete {{Model.Name}} Result = CommonResponse & {data: {delete_ {{Model.GraphqlName}} _ by_pk: {id: string;} `

In addition to the main types, it also includes the definition of the return value of adding, deleting, changing and checking API.

The knowledge points related to the text/template library are as follows:

Limit the scope of access through * * with * * so that you don't have to prefix each field with a .Model.Fields prefix in the code of {{- with xxx}} and {{- end}}

Iterate through the range to access the array and generate the corresponding code according to each element in the array

Through if judgment, different codes are generated according to the different definitions of attributes in the json file.

Custom function * * ConvertTypeForTs * *, which converts the graphql type defined in json to the corresponding type in typescript. Custom functions are used to avoid writing too much logic code in the template

Generate API

Only the API of the graphql request is generated here to match the illuminant project. The object used for the parameters and return values of API is in the type definition automatically generated above.

Const APITmpl = `/ / @ ts-ignore/* eslint-disable * / import {Graphql} from'.. / utils' Const gqlGet {{if. Name}} List = `+ "` query get_item_list ($limit: Int = 10, $offset: Int = 0 {{- Model.Fields}} {{- Model.IsSearch}, ${{.Name}: {{- end} {{- end} {{- end}) {Model.GraphqlName} (order_by: {Model.GraphqlName}, limit: $limit) Offset: $offset {{. Model.GenGraphqlSearchWhere false}}) {{- with .Model.Fields}} {{- range.}} {{- end}} {{- end} {{- Model.GenGraphqlSearchWhere true}} _ aggregate ({{. Model.GenGraphqlSearchWhere true}}) {aggregate {Model.Model.Fields} `+ "`" + ` Const gqlCreate {{.Model.Name}} = `+ "`" + `mutation create_item ({{.Model.GenGraphqlInsertParamDefinations}}) {insert_ {{Model.GraphqlName}} (objects: {.Model.GenGraphqlInsertParams}}) {Model.` + "`" + ` Const gqlUpdate {{.Model.Name}} = `+ "` + `mutation update_item_by_pk ($id: uuidships, {{.Model.GenGraphqlUpdateParamDefinations}}) {update_ {{Model.GraphqlName}} _ by_pk (pk_columns: {id: $id}, _ set: {Model.GenGraphqlUpdateParams}) {Model.GenGraphqlUpdateParams}}) {Model.` +` Const gqlDelete {{.Model.Name} = `+ "`" + `mutation delete_item_by_pk ($id: uuid!) {delete_ {{Model.GraphqlName}} _ by_pk (id: $id) {id}` + "`" +`; export async function get {{Model.Name}} List (params: API. {{Model.Name}} Item & API.PageInfo) {const gqlVar = {limit: params.pageSize? Params.pageSize: 10, offset: params.current & & params.pageSize? (params.current-1) * params.pageSize: 0, {{- with .Model.Fields}} {{- range.}} {{- if .IsSearch}: params. {{.Name}}?'%'+ params. {{.Name}} +'%':'%', {{- end} {{- end}} {{- end} Return Graphql (gqlGet {{.Model.Name}} List, gqlVar) } export async function create {{with. Name}} (params: API. {{Model.Name}} Item) {const gqlVar = {{- Model.Fields}} {{- Model.NotInsert}} {{- if .IsPageRequired} {name}: params. {{name}, {{- else} {{name}: params. {{name}}? Params. {{.Name}}: null, {{- end}} {{- end}}; return Graphql (gqlCreate {{.Model.Name}}, gqlVar) } export async function update {{if. Name}} (params: API. {{Model.Name}} Item) {const gqlVar = {id: params.id, {{- Model.Fields}} {{- range.}} {{- if .IsPageRequired} {{- if .IsPageRequired}}: params. {{name}, {- else} {{.Name}: params. {{name}? Params. {{end}}: null, {{- end}} {{- end}} {{- end}}; return Graphql (gqlUpdate {{.Model.Name}}, gqlVar);} export async function delete {{.Model.Name}} (id: string) {return Graphql (gqlDelete {{.Model.Name}}, {id});} `

Several custom functions are also used in this template, GenGraphqlSearchWhere,GenGraphqlInsertParams,**GenGraphqlUpdateParams * *, and so on.

Generate list pages, add and edit pages

The final step is to generate the page. The list page is the main page:

Const PageListTmpl = `import {useRef, useState} from 'react';import {PageContainer} from' @ ant-design/pro-layout';import {Button, Modal, Popconfirm, message} from 'antd';import {PlusOutlined} from' @ ant-design/icons';import type {ActionType, ProColumns} from'@ ant-design/pro-table';import ProTable from'@ ant-design/pro-table' Import {get {{Model.Name}} List, create {{.Model.Name}}, update {{.Model.Name}} from'{Page.ApiImport}}'; import {{.Model.Name}} Add from'. / {{Model.Name}} Add';import {{.Model.Name}} Edit from'. / {.Model.Name} Edit';export default () = > {Model.Name}} Edit';export default () Const [modalAddVisible, setModalAddVisible] = useState (false); const [modalEditVisible, setModalEditVisible] = useState (false); const [record, setRecord] = useState ({}) Const columns: ProColumns [] = [{{- with .Model.Fields}} {{- range.}} {{- if .IsColumn}} {title:'{{.title}}', dataIndex:'{{.name}}', {{- if not .IsSearch}} hideInSearch: true, {{- end} {{- end}} {{- / * end for if .IsColumn * /}} {{- end}} {{- / * end for range. * /} {{- end}} {{- / * end for with * /}} {title: 'operation', valueType: 'option', render: (_, rd) = > [{setModalEditVisible (true); setRecord (rd) }} > modify, {const response = await delete {{.Model.Name}} (rd.id as string); if (response.code = 10000) message.info (`+ "`" + `TODO: [${Model.Name}] deleted successfully` + "`" +`) Else message.warn (`+ "`" + `TODO: [${rd.TODO}] deletion failed` + "`" +`); tableRef.current?.reload ();}} > delete,],},]; const addItem = async (values: any) = > {console.log (values) Const response = await create {{.Model.Name} (values); if (response.code! = = 10000) {message.error ('failed to create TODO');} if (response.code = 10000) {setModalAddVisible (false); tableRef.current?.reload ();}}; const editItem = async (values: any) = > {values.id = record.id; console.log (values) Const response = await update {{.Model.Name} (values); if (response.code! = = 10000) {message.error ('failed to edit TODO');} if (response.code = 10000) {setModalEditVisible (false); tableRef.current?.reload ();}}; return ([{setModalAddVisible (true)) }} > New,]} request= {async (params: API. {{Model.Name}} Item & API.PageInfo) = > {const resp = await get {{.Model.Name}} List (params) Return {data: resp.data. {{.Model.GraphqlName}}, total: resp.data. {Model.GraphqlName} _ aggregate.aggregate.count,};}} / > setModalAddVisible (false)} > setModalEditVisible (false)} >);}; `

There is little difference between new pages and editing pages, and they are defined separately so that they can be expanded in the future. New page:

Const PageAddTmpl = `Model.GenPageImportCtrls}} import {formLayout} from'@ / common';import {Row, Col, Space} from 'antd' Export default (props: any) = > {return (({dom}),} > {{- with .Model.Fields}} {{- range.}} {{- .GenPageCtrl}} {{- end}} {{- end}}); `

One place in the page generation that bothers me for a while is that there is a conflict with the text/template tag in the page, that is, the display of {{. For example, the submitter= {{"{"}} above needs to display {{2 characters directly on the page, but the part that is framed by {{}} is the part of the template that needs to be replaced.

Therefore, where {{needs to be displayed in the template, {{"{"}} can be used instead.

At this point, I believe that everyone on the "golang standard library template code generation method is what" have a deeper understanding, might as well to the actual operation of it! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development