From WikiChip
Module:package

To add this template, simple add
{{package}}
to the page and save. The chip infobox will have a small [Edit Values] button at the top-right corner which can be used to add values using a form.
local p = {}
local origArgs

function p.add_file_prefix(str)
  if string.match(string.lower(str), '^file:') then
    return str
  else
    return 'File:' .. str
  end
end

function p.add_separator(box, title)
  box:tag('tr')
           :tag('td')
           :attr('class', 'header')
           :attr('colspan', '2')
           :wikitext(title)
end

function add_header(box, str)
      box
        :tag('tr')
          :tag('td')
            :attr('class', 'header')
            :attr('colspan', '2')
            :wikitext(str)
end

function p.add_entry(value, right)
  local e = mw.html.create('tr')
  e:tag('td')
    :attr('class', 'label')
    :wikitext(value)
  e:node(right)
  return e   
end

function has_arg(name)
	-- The argument can exist and be empty or not exist at all
	return string.len(origArgs[name] or '') > 0
end

function arg(name)
	return origArgs[name]
end

function p.set_val(prop, val)
	p.frame:preprocess('{{#set: ' .. prop .. '=' .. val .. '}}')	
end

function p.pkg(frame)
	
	p.frame = frame
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame.args
    end
	
	
    local infobox = mw.html.create('table')

    infobox
        :attr('class', 'infobox')
        
    infobox
    	:tag('tr')
			:tag('td'):attr('colspan', '2')
			:tag('small'):attr('style', 'float: left; font-weight: bold;')
            :wikitext('[[Special:FormEdit/package/' .. frame:preprocess('{{FULLPAGENAME}}') .. '|<i class="fa fa-edit"></i>Edit Values]]')

    -- header
    if has_arg('name') then
      infobox
        :tag('tr')
          :tag('td')
            :attr('class', 'header-main')
            :attr('colspan', '2')
            :wikitext('[[name::' .. arg('name') .. ']]')
    end


    -- ####################################################################
    -- some general info first
    p.add_separator(infobox, 'General Info')

    local function entry(a)
        local label, arg_name = unpack(a)
        if not has_arg(arg_name) then return end
        local function text(i, value)
            local prop_name = a.prop_name or arg_name -- {} for none
            if type(prop_name) == 'table' then
                if i > #prop_name then
                    if a.print then return a.print(value) end
                    return value
                end
                prop_name = prop_name[i]
            end
            return '[[' .. prop_name .. '::' .. value ..
                (a.print and ('| ]]' .. a.print(value)) or ']]')
        end
        local td = mw.html.create('td'):wikitext(text(1, arg(arg_name)))
        for i = 2, (a.max_args or 1) do
            local value = origArgs[arg_name .. ' ' .. i]
            if not value or value == '' then break end
            td:wikitext((a.sep or ', ') .. text(i, value))
        end
        if label then infobox:node(p.add_entry(label, td)) end
        return td
    end
    local function link(s) return '[[' .. mw.ustring.lower(s) .. '|' .. s .. ']]' end

    local uarch_link
    if has_arg('designer') then
        uarch_link = function(s) return '[[' .. mw.ustring.lower(arg('designer') ..
            '/microarchitectures/' .. s) .. '|' .. s .. ']]' end
        local td = entry{nil, 'designer', max_args=10, print=link}
        infobox:node(p.add_entry('Designer', td:attr('style', 'width: 99%;')))
    end

    if has_arg('first launched') or has_arg('first announced') then
        local release, sep = mw.html.create('td'), ''
        if has_arg('first announced') then
            release:wikitext('[[first announced::' .. arg('first announced') .. ']] (announced)')
            sep = '<br/>'
        end
        if has_arg('first launched') then
            release:wikitext(sep .. '[[first launched::' .. arg('first launched') .. ']] (launched)')
        end
        infobox:node(p.add_entry('Introduction', release))
    end

    entry{'Market', 'market', max_args=5, prop_name='market segment'}
    entry{'Microarchitecture', 'microarch', max_args=10,
        prop_name='microarchitecture', print=uarch_link}
    entry{'Chipset', 'chipset', max_args=10}
    entry{'<abbr title="Thermal Design Power">TDP</abbr>', 'tdp', max_args=10}

    if has_arg('package name') or has_arg('package type') then
        p.add_separator(infobox, 'Package')
        entry{'Name', 'package name', max_args=10, prop_name='package', sep=',<br/>'}
        entry{'Type', 'package type'}
        entry{'Contacts', 'package contacts'}
        entry{'Dimension', 'package dimension', max_args=3, sep=' × ',
            prop_name={'package length', 'package width', 'package height'}}
        entry{'Pitch', 'package pitch', max_args=2, sep=' × '}
    end

    if has_arg('socket name') or has_arg('socket type') then
        p.add_separator(infobox, 'Socket')
        entry{'Name', 'socket name', prop_name='socket', max_args=10, sep=',<br/>'}
        entry{'Type', 'socket type', prop_name={}}
    end

    -- ####################################################################
    -- ####################################################################
    -- Successon
	if has_arg('successor') or has_arg('predecessor') then
		add_header(infobox, 'Succession')
		
		local s = infobox:tag('tr')
		local td = s:tag('td'):attr('colspan', '2')
		local d1 = td:tag('div'):attr('style', 'display: inline-flex;')
		local d2 = td:tag('div'):attr('style', 'display: inline-flex; float: right;')
		if has_arg('predecessor') then
			
		    local list
		    if has_arg('predecessor link') then
				list = '[[' .. arg('predecessor link') .. '|' .. arg('predecessor') .. ']]'
			else
				list = '[[' .. arg('predecessor') .. ']]'
			end
		    for i = 2, 10 do
		    	if not has_arg('predecessor ' .. i) then break end
		    	if has_arg('predecessor ' .. i .. ' link') then
		    		list = list .. '<br>[[' .. arg('predecessor ' .. i .. ' link') .. '|' .. arg('predecessor ' .. i) .. ']]'
	    		else
		    		list = list .. '<br>[[' .. arg('predecessor ' .. i) .. ']]'
    			end
			end
			
			d1:tag('div')
				:attr('style', 'float: left; padding-right: 10px; margin: auto 5px;')
				:wikitext('<i class="fa fa-chevron-left"></i>')
			d1:tag('div')
				:attr('style', 'float: left;')
				:wikitext(list)
		end
		if has_arg('successor') then
			local list
		    if has_arg('successor link') then
				list = '[[' .. arg('successor link') .. '|' .. arg('successor') .. ']]'
			else
				list = '[[' .. arg('successor') .. ']]'
			end
		    for i = 2, 10 do
		    	if not has_arg('successor ' .. i) then break end
		    	if has_arg('successor ' .. i .. ' link') then
		    		list = list .. '<br>[[' .. arg('successor ' .. i .. ' link') .. '|' ..
		    			arg('successor ' .. i) .. ']]'
	    		else
		    		list = list .. '<br>[[' .. arg('successor ' .. i) .. ']]'
    			end
			end
			
			d2:tag('div')
				:attr('style', 'float: left;')
				:wikitext(list)
			d2:tag('div')
				:attr('style', 'float: right; padding-left: 10px; margin: auto 5px;')
				:wikitext('<i class="fa fa-chevron-right"></i>')
		end
	end
    -- Contemporary
	if has_arg('contemporary') then
		add_header(infobox, 'Contemporary')
		
		local s = infobox:tag('tr')
		local td = s:tag('td'):attr('colspan', '2')
		
		td:attr('style', 'text-align: center;')

	    local list
	    if has_arg('contemporary link') then
			list = '[[' .. arg('contemporary link') .. '|' .. arg('contemporary') .. ']]'
		else
			list = '[[' .. arg('contemporary') .. ']]'
		end
	    for i = 2, 10 do
	    	if not has_arg('contemporary ' .. i) then break end
	    	if has_arg('contemporary ' .. i .. ' link') then
	    		list = list .. '<br>[[' .. arg('contemporary ' .. i .. ' link') .. '|' .. arg('contemporary ' .. i) .. ']]'
    		else
	    		list = list .. '<br>[[' .. arg('contemporary ' .. i) .. ']]'
			end
		end
		
		td:wikitext(list)
	end


	infobox:wikitext('[[instance of::package| ]]')
	infobox:wikitext('[[Category:all ic packages]]')
	
    return infobox
end

return p