mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Merge template functions "dict/Dict/mergeinto" (#23932)
One of the steps in #23328 Before there were 3 different but similar functions: dict/Dict/mergeinto The code was just copied & pasted, no test. This PR defines a new stable `dict` function, it covers all the 3 old functions behaviors, only +160 -171 Future developers do not need to think about or guess the different dict functions, just use one: `dict` Why use `dict` but not `Dict`? Because there are far more `dict` than `Dict` in code already ......
This commit is contained in:
		
							
								
								
									
										47
									
								
								modules/templates/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								modules/templates/util.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// Copyright 2023 The Gitea Authors. All rights reserved.
 | 
			
		||||
// SPDX-License-Identifier: MIT
 | 
			
		||||
 | 
			
		||||
package templates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func dictMerge(base map[string]any, arg any) bool {
 | 
			
		||||
	if arg == nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	rv := reflect.ValueOf(arg)
 | 
			
		||||
	if rv.Kind() == reflect.Map {
 | 
			
		||||
		for _, k := range rv.MapKeys() {
 | 
			
		||||
			base[k.String()] = rv.MapIndex(k).Interface()
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dict is a helper function for creating a map[string]any from a list of key-value pairs.
 | 
			
		||||
// If the key is dot ".", the value is merged into the base map, just like Golang template's dot syntax: dot means current
 | 
			
		||||
// The dot syntax is highly discouraged because it might cause unclear key conflicts. It's always good to use explicit keys.
 | 
			
		||||
func dict(args ...any) (map[string]any, error) {
 | 
			
		||||
	if len(args)%2 != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("invalid dict constructor syntax: must have key-value pairs")
 | 
			
		||||
	}
 | 
			
		||||
	m := make(map[string]any, len(args)/2)
 | 
			
		||||
	for i := 0; i < len(args); i += 2 {
 | 
			
		||||
		key, ok := args[i].(string)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return nil, fmt.Errorf("invalid dict constructor syntax: unable to merge args[%d]", i)
 | 
			
		||||
		}
 | 
			
		||||
		if key == "." {
 | 
			
		||||
			if ok = dictMerge(m, args[i+1]); !ok {
 | 
			
		||||
				return nil, fmt.Errorf("invalid dict constructor syntax: dot arg[%d] must be followed by a dict", i)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			m[key] = args[i+1]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user