mirror of
https://github.com/home-assistant/home-assistant.io.git
synced 2025-12-10 14:46:47 -06:00
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: ecspiegel <87676266+ecspiegel@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com> Co-authored-by: alawadhi3000 <5523980+alawadhi3000@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Franck Nijhof <git@frenck.dev> Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com> Co-authored-by: staticdev <staticdev-support@proton.me> Co-authored-by: tronikos <tronikos@users.noreply.github.com> Co-authored-by: AlCalzone <dominic.griesel@nabucasa.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: essys <essys@users.noreply.github.com> Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com> Co-authored-by: Gord <31004434+googanhiem@users.noreply.github.com> Co-authored-by: Darren Griffin <darren.griffin@live.co.uk> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: hanwg <han.wuguang@gmail.com> Co-authored-by: Adam W <35391288+A-damW@users.noreply.github.com> Co-authored-by: Hessel <hesselonline@users.noreply.github.com> Co-authored-by: Damien Sorel <mistic@strangeplanet.fr> Co-authored-by: Tempura San <tempura.san@gmail.com> Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com> Co-authored-by: J. Diego Rodríguez Royo <jdrr1998@hotmail.com> Co-authored-by: lexitus <38081592+lexitus@users.noreply.github.com> Co-authored-by: Sid <27780930+autinerd@users.noreply.github.com> Co-authored-by: Evgeny Sureev <u@litka.ru> Co-authored-by: Stefan Agner <stefan@agner.ch> Co-authored-by: TomArm <TomArm@users.noreply.github.com> Co-authored-by: starkillerOG <starkiller.og@gmail.com> Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com> Co-authored-by: Guillaume Rischard <github@stereo.lu> Co-authored-by: Geoff <85890024+Thulrus@users.noreply.github.com> Co-authored-by: GhoweVege <85890024+GhoweVege@users.noreply.github.com> Co-authored-by: Logan Rosen <loganrosen@gmail.com> Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: RanTheLab <RanTheLab@users.noreply.github.com> Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com> Co-authored-by: John Hess <john@h3ss.com> Co-authored-by: Marco <cdrfun@cdrfun.eu> Co-authored-by: robthebold <38596885+robthebold@users.noreply.github.com> Co-authored-by: Paulus Schoutsen <balloob@gmail.com> Co-authored-by: Pieter Rautenbach <parautenbach@gmail.com> Co-authored-by: Tsvi Mostovicz <ttmost@gmail.com> Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Galorhallen <12990764+Galorhallen@users.noreply.github.com> Co-authored-by: Jan-Philipp Benecke <jan-philipp@bnck.me> Co-authored-by: Jan Čermák <sairon@users.noreply.github.com> Co-authored-by: Norbert Rittel <norbert@rittel.de> Co-authored-by: Mr. Snyds <41122989+mrsnyds@users.noreply.github.com> Co-authored-by: Allen Porter <allen.porter@gmail.com> Co-authored-by: Ludovic BOUÉ <lboue@users.noreply.github.com> Co-authored-by: threatdisplay <ajbriones@gmail.com> Co-authored-by: Kamil Breguła <mik-laj@users.noreply.github.com> Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com> Co-authored-by: Timothy <6560631+TimoPtr@users.noreply.github.com> Co-authored-by: Joris Pelgröm <jpelgrom@users.noreply.github.com> Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com> Co-authored-by: Arie Catsman <120491684+catsmanac@users.noreply.github.com> Co-authored-by: Marko Dimjašević <marko@dimjasevic.net> Co-authored-by: karwosts <32912880+karwosts@users.noreply.github.com> Co-authored-by: Guido Schmitz <Shutgun@users.noreply.github.com>
196 lines
6.8 KiB
Ruby
196 lines
6.8 KiB
Ruby
module Jekyll
|
|
class ConfigurationBlock < Liquid::Block
|
|
TYPE_LINKS = {
|
|
'action' => '/docs/scripts/',
|
|
'device_class' => '/integrations/homeassistant/#device-class',
|
|
'template' => '/docs/configuration/templating/',
|
|
'icon' => '/integrations/homeassistant/#icon',
|
|
'selector' => '/docs/blueprint/selectors/',
|
|
}
|
|
|
|
TYPES = [
|
|
'action', 'boolean', 'string', 'integer', 'float', 'time', 'template',
|
|
'device_class', 'icon', 'map', 'list', 'date', 'datetime', 'any',
|
|
'selector',
|
|
]
|
|
|
|
MIN_DEFAULT_LENGTH = 30
|
|
|
|
def initialize(tag_name, text, tokens)
|
|
super
|
|
@component, @platform = text.strip.split('.', 2)
|
|
end
|
|
|
|
def slug(key)
|
|
key.downcase.strip.gsub(' ', '-').gsub(/[^\w\-]/, '')
|
|
end
|
|
|
|
def type_class(type)
|
|
((type.is_a? Array) ? type.join(' ') : type).downcase
|
|
end
|
|
|
|
def type_link(type, component: nil)
|
|
if type.include? ','
|
|
type = type.split(',')
|
|
end
|
|
|
|
if type.is_a? Array
|
|
return (type.map { |t| type_link(t, component: component) }).join(' | ')
|
|
end
|
|
|
|
type.strip!
|
|
if TYPE_LINKS.include? type.downcase
|
|
url = TYPE_LINKS[type.downcase] % {component: component}
|
|
"<a href=\"%s\">%s</a>" % [url, type]
|
|
else
|
|
type
|
|
end
|
|
end
|
|
|
|
def required_value(value)
|
|
if value === true
|
|
"Required"
|
|
elsif value === false
|
|
"Optional"
|
|
else
|
|
value.strip.titlecase
|
|
end
|
|
end
|
|
|
|
def render_config_vars(vars:, component:, platform:, converter:, classes: nil, parent_type: nil)
|
|
result = Array.new
|
|
result << "<div class='#{classes}'>"
|
|
|
|
result << vars.map do |key, attr|
|
|
markup = Array.new
|
|
# There are spaces around the "{key}", to improve double-click selection in Chrome.
|
|
markup << "<div class='config-vars-item'><div class='config-vars-label'><span class='config-vars-label-name'> #{key} </span>"
|
|
|
|
if attr.key? 'type'
|
|
|
|
# Check if the type (or list of types) are valid
|
|
if attr['type'].kind_of? Array
|
|
attr['type'].each do |type|
|
|
raise ArgumentError, "Configuration type '#{type}' for key '#{key}' is not a valid type in the documentation."\
|
|
" See: https://developers.home-assistant.io/docs/documenting/create-page#configuration" unless \
|
|
TYPES.include? type
|
|
end
|
|
else
|
|
raise ArgumentError, "Configuration type '#{attr['type']}' for key '#{key}' is not a valid type in the documentation."\
|
|
" See: https://developers.home-assistant.io/docs/documenting/create-page#configuration" unless \
|
|
TYPES.include? attr['type']
|
|
end
|
|
|
|
markup << "<span class='config-vars-type'>#{type_link(attr['type'], component: component)}</span>"
|
|
else
|
|
# Type is missing, which is required (unless we are in a list or template)
|
|
raise ArgumentError, "Configuration key '#{key}' is missing a type definition" \
|
|
unless ['list', 'template'].include? parent_type
|
|
end
|
|
|
|
defaultValue = ""
|
|
isDefault = false
|
|
if attr.key? 'default' and not attr['default'].to_s.empty?
|
|
isDefault = true
|
|
defaultValue = converter.convert(attr['default'].to_s)
|
|
elsif attr['type'].to_s.include? 'boolean'
|
|
# If the type is a boolean, a default key is required
|
|
raise ArgumentError, "Configuration key '#{key}' is a boolean type and"\
|
|
" therefore, requires a default."
|
|
end
|
|
|
|
if attr.key? 'required'
|
|
# Check if required is a valid value
|
|
raise ArgumentError, "Configuration key '#{key}' required field must be specified as: "\
|
|
"true, false, inclusive or exclusive."\
|
|
unless [true, false, 'inclusive', 'exclusive'].include? attr['required']
|
|
|
|
isTrue = attr['required'].to_s == 'true'
|
|
startSymbol = isTrue ? ' ' : ' ('
|
|
endSymbol = isTrue ? '' : ')'
|
|
showDefault = isDefault && (defaultValue.length <= MIN_DEFAULT_LENGTH)
|
|
shortDefaultValue = ""
|
|
if showDefault
|
|
shortDefaultValue = defaultValue
|
|
shortDefaultValue.slice!("<p>")
|
|
shortDefaultValue.slice!("</p>")
|
|
shortDefaultValue = shortDefaultValue.strip
|
|
shortDefaultValue = ", default: " + shortDefaultValue
|
|
end
|
|
|
|
markup << "<span class='config-vars-required'>#{startSymbol}<span class='#{attr['required'].to_s}'>#{required_value(attr['required'])}</span><span class='default'>#{shortDefaultValue}</span>#{endSymbol}</span>"
|
|
end
|
|
|
|
markup << "<a name='#{slug(key)}' class='title-link' href='\##{slug(key)}'></a></div><div class='config-vars-description-and-children'>"
|
|
|
|
if attr.key? 'description'
|
|
markup << "<span class='config-vars-description'>#{converter.convert(attr['description'].to_s)}</span>"
|
|
else
|
|
# Description is missing
|
|
raise ArgumentError, "Configuration key '#{key}' is missing a description."
|
|
end
|
|
|
|
if isDefault && defaultValue.length > MIN_DEFAULT_LENGTH
|
|
markup << "<div class='config-vars-default'>\nDefault: #{defaultValue}</div>"
|
|
end
|
|
markup << "</div>"
|
|
|
|
# Check for nested configuration variables
|
|
if attr.key? 'keys'
|
|
markup << render_config_vars(
|
|
vars: attr['keys'], component: component,
|
|
platform: platform, converter: converter,
|
|
classes: 'nested', parent_type: attr['type'])
|
|
end
|
|
|
|
markup << "</div>"
|
|
end
|
|
|
|
result << "</div>"
|
|
result.join
|
|
end
|
|
|
|
def render(context)
|
|
if @component.nil? and @platform.nil?
|
|
page = context.environments.first['page']
|
|
@component, @platform = page['slug'].split('.', 2)
|
|
end
|
|
|
|
contents = super(context)
|
|
|
|
component = Liquid::Template.parse(@component).render context
|
|
platform = Liquid::Template.parse(@platform).render context
|
|
|
|
site = context.registers[:site]
|
|
converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
|
|
|
|
vars = SafeYAML.load(contents)
|
|
|
|
linkId = [component, platform, 'configuration-variables']
|
|
.compact
|
|
.reject(&:empty?)
|
|
.join('-')
|
|
|
|
|
|
<<~MARKUP
|
|
<div class="config-vars">
|
|
<h4>
|
|
Configuration Variables <a class="title-link" name="#{linkId}" href="##{linkId}"></a>
|
|
</h4>
|
|
<div class="configuration-link">
|
|
<a href="/docs/configuration/" target="_blank">Looking for your configuration file?</a>
|
|
</div>
|
|
#{render_config_vars(
|
|
vars: vars,
|
|
component: component,
|
|
platform: platform,
|
|
converter: converter
|
|
)}
|
|
</div>
|
|
MARKUP
|
|
end
|
|
end
|
|
end
|
|
|
|
Liquid::Template.register_tag('configuration', Jekyll::ConfigurationBlock)
|