summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-ddns/luasrc/view
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2014-12-03 15:17:05 +0100
committerJo-Philipp Wich <jow@openwrt.org>2015-01-08 16:26:20 +0100
commit1bb4822dca6113f73e3bc89e2acf15935e6f8e92 (patch)
tree35e16f100466e4e00657199b38bb3d87d52bf73f /applications/luci-app-ddns/luasrc/view
parent9edd0e46c3f880727738ce8ca6ff1c8b85f99ef4 (diff)
Rework LuCI build system
* Rename subdirectories to their repective OpenWrt package names * Make each LuCI module its own standalone package * Deploy a shared luci.mk which is used by each module Makefile Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Diffstat (limited to 'applications/luci-app-ddns/luasrc/view')
-rw-r--r--applications/luci-app-ddns/luasrc/view/admin_status/index/ddns.htm1
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/detail_logview.htm56
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/detail_lvalue.htm22
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/detail_value.htm9
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/overview_doubleline.htm10
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/overview_enabled.htm15
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/overview_startstop.htm17
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/overview_status.htm208
-rw-r--r--applications/luci-app-ddns/luasrc/view/ddns/system_status.htm158
9 files changed, 496 insertions, 0 deletions
diff --git a/applications/luci-app-ddns/luasrc/view/admin_status/index/ddns.htm b/applications/luci-app-ddns/luasrc/view/admin_status/index/ddns.htm
new file mode 100644
index 0000000000..9791065083
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/admin_status/index/ddns.htm
@@ -0,0 +1 @@
+<%+ddns/system_status%>
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/detail_logview.htm b/applications/luci-app-ddns/luasrc/view/ddns/detail_logview.htm
new file mode 100644
index 0000000000..494b7435cd
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/detail_logview.htm
@@ -0,0 +1,56 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ detail_logview.htm ++ -->
+<script type="text/javascript">//<![CDATA[
+ function onclick_logview(section, bottom) {
+ // get elements
+ var txt = document.getElementById("cbid.ddns." + section + "._logview.txt"); // TextArea
+ if ( !txt ) { return; } // security check
+
+ XHR.get('<%=luci.dispatcher.build_url("admin", "services", "ddns", "logview")%>/' + section, null,
+ function(x) {
+ if (x.responseText == "_nodata_")
+ txt.value = "<%:File not found or empty%>";
+ else
+ txt.value = x.responseText;
+ if (bottom)
+ txt.scrollTop = txt.scrollHeight;
+ else
+ txt.scrollTop = 0; }
+ );
+ }
+//]]></script>
+
+<%+cbi/valueheader%>
+
+<br />
+
+<%
+-- one button on top, one at the buttom
+%>
+<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, false)"
+<%=
+attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
+%> />
+
+<br /><br />
+
+<%
+-- set a readable style taken from openwrt theme for textarea#syslog
+-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
+%>
+<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 500px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
+<%=
+attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
+%> >
+<%-=pcdata(self:cfgvalue(section))-%>
+</textarea>
+<br /><br />
+
+<%
+-- one button on top, one at the buttom
+%>
+<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, true)"
+<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Dynamic DNS ++ detail_logview.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/detail_lvalue.htm b/applications/luci-app-ddns/luasrc/view/ddns/detail_lvalue.htm
new file mode 100644
index 0000000000..d516837b2b
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/detail_lvalue.htm
@@ -0,0 +1,22 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ detail_lvalue.htm ++ -->
+<!-- no value header to supress next line -->
+&#160;
+<% if self.widget == "select" then %>
+ <select class="cbi-input-select" onchange="cbi_d_update(this.id)"<%= attr("id", cbid) .. attr("name", cbid) .. ifattr(self.size, "size") %>>
+ <% for i, key in pairs(self.keylist) do -%>
+ <option id="cbi-<%=self.config.."-"..section.."-"..self.option.."-"..key%>"<%= attr("value", key) .. ifattr(tostring(self:cfgvalue(section) or self.default) == key, "selected", "selected") %>><%=striptags(self.vallist[i])%></option>
+ <%- end %>
+ </select>
+<% elseif self.widget == "radio" then
+ local c = 0
+ for i, key in pairs(self.keylist) do
+ c = c + 1
+%>
+ <input class="cbi-input-radio" onclick="cbi_d_update(this.id)" onchange="cbi_d_update(this.id)" type="radio"<%= attr("id", cbid..c) .. attr("name", cbid) .. attr("value", key) .. ifattr((self:cfgvalue(section) or self.default) == key, "checked", "checked") %> />
+ <label<%= attr("for", cbid..c) %>><%=self.vallist[i]%></label>
+<% if c == self.size then c = 0 %><% if self.orientation == "horizontal" then %>&#160;<% else %><br /><% end %>
+<% end end %>
+<% end %>
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Dynamic DNS ++ detail_lvalue.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/detail_value.htm b/applications/luci-app-ddns/luasrc/view/ddns/detail_value.htm
new file mode 100644
index 0000000000..7cb28e282e
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/detail_value.htm
@@ -0,0 +1,9 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ detail_value.htm ++ -->
+<%+cbi/valueheader%>
+ <input type="text" class="cbi-input-text" style="width: 10em;" onchange="cbi_d_update(this.id)"<%=
+ attr("name", cbid) .. attr("id", cbid) .. attr("value", self:cfgvalue(section) or self.default) ..
+ ifattr(self.size, "size") .. ifattr(self.placeholder, "placeholder")
+ %> />
+<!-- no value footer to supress next line -->
+<!-- ++ END ++ Dynamic DNS ++ detail_value.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/overview_doubleline.htm b/applications/luci-app-ddns/luasrc/view/ddns/overview_doubleline.htm
new file mode 100644
index 0000000000..1d1b4be019
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/overview_doubleline.htm
@@ -0,0 +1,10 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ overview_doubleline.htm ++ -->
+<%+cbi/valueheader%>
+
+<span id="<%=cbid%>.one"><%=self:set_one(section)%></span>
+<br />
+<span id="<%=cbid%>.two"><%=self:set_two(section)%></span>
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Dynamic DNS ++ overview_doubleline.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/overview_enabled.htm b/applications/luci-app-ddns/luasrc/view/ddns/overview_enabled.htm
new file mode 100644
index 0000000000..64b3dae455
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/overview_enabled.htm
@@ -0,0 +1,15 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ overview_enabled.htm ++ -->
+<%+cbi/valueheader%>
+
+<input type="hidden" value="1"<%=
+ attr("name", "cbi.cbe." .. self.config .. "." .. section .. "." .. self.option)
+%> />
+ <!-- modified to call own function -->
+<input class="cbi-input-checkbox" onclick="cbi_d_update(this.id)" onchange="onchange_enabled(this.id)" type="checkbox"<%=
+ attr("id", cbid) .. attr("name", cbid) .. attr("value", self.enabled or 1) ..
+ ifattr((self:cfgvalue(section) or self.default) == self.enabled, "checked", "checked")
+%> />
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Dynamic DNS ++ overview_enabled.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/overview_startstop.htm b/applications/luci-app-ddns/luasrc/view/ddns/overview_startstop.htm
new file mode 100644
index 0000000000..8255aa63f3
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/overview_startstop.htm
@@ -0,0 +1,17 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ overview_startstop.htm ++ -->
+<%+cbi/valueheader%>
+
+<% if self:cfgvalue(section) ~= false then
+-- We need to garantie that function cfgvalue run first to set missing parameters
+%>
+ <!-- style="font-size: 100%;" needed for openwrt theme to fix font size -->
+ <!-- type="button" onclick="..." enable standard onclick functionalty -->
+ <input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="font-size: 100%;" type="button" onclick="onclick_startstop(this.id)"
+ <%=
+ attr("name", section) .. attr("id", cbid) .. attr("value", self.inputtitle) .. ifattr(self.disabled, "disabled")
+ %> />
+<% end %>
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Dynamic DNS ++ overview_startstop.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/overview_status.htm b/applications/luci-app-ddns/luasrc/view/ddns/overview_status.htm
new file mode 100644
index 0000000000..37c54be25f
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/overview_status.htm
@@ -0,0 +1,208 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ overview_status.htm ++ -->
+<script type="text/javascript">//<![CDATA[
+
+ // variables to store version information
+ var luci_version
+ var luci_build
+ var ddns_version
+ var ddns_required
+
+ // helper to extract section from objects id
+ // cbi.ddns.SECTION._xyz
+ function _id2section(id) {
+ var x = id.split(".");
+ return x[2];
+ }
+
+ // helper to move status data to the relevant
+ // screen objects
+ // called by XHR.poll and onclick_startstop
+ function _data2elements(data) {
+ // DDNS Service
+ // fill Version informations
+ luci_version = data[0].luci_ver
+ luci_build = data[0].luci_build
+ ddns_version = data[0].script_ver
+ ddns_required = data[0].script_min
+
+ // Service sections
+ for( i = 1; i < data.length; i++ )
+ {
+ var section = data[i].section // Section to handle
+ var cbx = document.getElementById("cbid.ddns." + section + ".enabled"); // Enabled
+ var btn = document.getElementById("cbid.ddns." + section + "._startstop"); // Start/Stop button
+ var rip = document.getElementById("cbid.ddns." + section + "._domainIP.two"); // Registered IP
+ var lup = document.getElementById("cbid.ddns." + section + "._update.one"); // Last Update
+ var nup = document.getElementById("cbid.ddns." + section + "._update.two"); // Next Update
+ if ( !(cbx && btn && rip && lup && nup) ) { return; } // security check
+
+ // process id
+ if (data[i].pid > 0) {
+ // stop always possible if process running
+ btn.value = "PID: " + data[i].pid;
+ btn.className = "cbi-button cbi-input-reset";
+ } else {
+ // default Start / enabled
+ btn.value = "<%:Start%>";
+ btn.className = "cbi-button cbi-input-apply";
+ }
+ btn.disabled = false; // button enabled
+
+ // last update
+ switch (data[i].datelast) {
+ case "_empty_":
+ lup.innerHTML = '<em><%:Unknown error%></em>' ;
+ break;
+ case "_never_":
+ lup.innerHTML = '<em><%:Never%></em>' ;
+ break;
+ default:
+ lup.innerHTML = data[i].datelast;
+ break;
+ }
+
+ // next update
+ switch (data[i].datenext) {
+ case "_empty_":
+ nup.innerHTML = '<em><%:Unknown error%></em>' ;
+ break;
+ case "_verify_":
+ nup.innerHTML = '<em><%:Verify%></em>';
+ break;
+ case "_runonce_":
+ case "_stopped_":
+ case "_disabled_":
+ if (cbx.checked && data[i].datenext == "_runonce_") {
+ nup.innerHTML = '<em><%:Run once%></em>';
+ } else if (cbx.checked) {
+ nup.innerHTML = '<em><%:Stopped%></em>';
+ } else {
+ nup.innerHTML = '<em><%:Disabled%></em>';
+ btn.value = '----------';
+ btn.className = "cbi-button cbi-input-button"; // no image
+ btn.disabled = true; // disabled
+ }
+ break;
+ default:
+ nup.innerHTML = data[i].datenext;
+ break;
+ }
+
+ // domain
+ // (data[i].domain ignored here
+
+ // registered IP
+ // rip.innerHTML = "Registered IP";
+ if (data[i].domain == "_nodomain_")
+ rip.innerHTML = '';
+ else if (data[i].reg_ip == "_nodata_")
+ rip.innerHTML = '<em><%:No data%></em>';
+ else
+ rip.innerHTML = data[i].reg_ip;
+
+ // monitored interfacce
+ // data[i].iface ignored here
+ }
+ }
+
+ // event handler for enabled checkbox
+ function onchange_enabled(id) {
+ // run original function in cbi.js
+ // whatever is done there
+ cbi_d_update(id);
+
+ var section = _id2section(id);
+ var cbx = document.getElementById("cbid.ddns." + section + ".enabled");
+ var btn = document.getElementById("cbid.ddns." + section + "._startstop");
+ if ( !(cbx && btn) ) { return; } // security check
+
+ var pid_txt = btn.value;
+ var pid_found = ( pid_txt.search("PID") >= 0 ) ? true : false;
+
+ if (pid_found) {
+ // btn.value = "PID: 0000";
+ btn.className = "cbi-button cbi-button-reset";
+ btn.disabled = false;
+ } else if (cbx.checked) {
+ btn.value = "<%:Start%>";
+ btn.className = "cbi-button cbi-button-apply";
+ btn.disabled = false;
+ } else {
+ btn.value = '----------';
+ btn.className = "cbi-button cbi-input-button"; // no image
+ btn.disabled = true; // disabled
+ }
+ }
+
+ // event handler for map.title link
+ function onclick_maptitle() {
+ var str = "<%:Version Information%>";
+ str += "\n\nluci-app-ddns:";
+ str += "\n\t<%:Version%>:\t" + luci_version;
+ str += "\n\t<%:Build%>:\t" + luci_build;
+ str += "\n\nddns-scripts <%:required%>:";
+ str += "\n\t<%:Version%>:\t" + ddns_required + " <%:or greater%>";
+ str += "\n\nddns-scripts <%:installed%>:";
+ str += "\n\t<%:Version%>:\t" + ddns_version;
+ str += "\n\n"
+ alert(str);
+ }
+
+ // event handler for start/stop button
+ function onclick_startstop(id) {
+ // extract section
+ var section = _id2section(id);
+ // get elements
+ var cbx = document.getElementById("cbid.ddns." + section + ".enabled"); // Enabled
+ var obj = document.getElementById("cbi-ddns-overview-status-legend"); // objext defined below to make in-/visible
+ if ( !(obj && cbx) ) { return; } // security check
+
+ // make me visible
+ obj.parentNode.style.display = "block";
+
+ // do start/stop
+ var btnXHR = new XHR();
+ btnXHR.get('<%=luci.dispatcher.build_url("admin", "services", "ddns", "startstop")%>/' + section + '/' + cbx.checked, null,
+ function(x, data) {
+ if (x.responseText == "_uncommited_") {
+ // we need a trick to display Ampersand "&" in stead of "&#38;" or "&amp;"
+ // after translation
+ txt="<%:Please [Save & Apply] your changes first%>";
+ alert( txt.replace(new RegExp("<%:&%>", "g"), "&") );
+ } else {
+ // should have data because status changed
+ // so update screen
+ if (data)
+ _data2elements(data);
+ }
+ // make me invisible
+ obj.parentNode.style.display = "none";
+ }
+ );
+ }
+
+ // force to immediate show status on page load (not waiting for XHR.poll)
+ XHR.get('<%=luci.dispatcher.build_url("admin", "services", "ddns", "status")%>', null,
+ function(x, data) {
+ _data2elements(data);
+ }
+ );
+
+ // define only ONE XHR.poll in a page because if one is running it blocks the other one
+ // optimum is to define on Map or Section Level from here you can reach all elements
+ // we need update every 15 seconds only
+ XHR.poll(15, '<%=luci.dispatcher.build_url("admin", "services", "ddns", "status")%>', null,
+ function(x, data) {
+ _data2elements(data);
+ }
+ );
+
+//]]></script>
+
+<fieldset class="cbi-section" style="display:none">
+ <legend id="cbi-ddns-overview-status-legend"><%:Applying changes%></legend>
+ <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
+ <span id="cbi-ddns-overview-status-text"><%:Waiting for changes to be applied...%></span>
+</fieldset>
+<!-- ++ END ++ Dynamic DNS ++ overview_status.htm ++ -->
diff --git a/applications/luci-app-ddns/luasrc/view/ddns/system_status.htm b/applications/luci-app-ddns/luasrc/view/ddns/system_status.htm
new file mode 100644
index 0000000000..db9d1d1a01
--- /dev/null
+++ b/applications/luci-app-ddns/luasrc/view/ddns/system_status.htm
@@ -0,0 +1,158 @@
+
+<!-- ++ BEGIN ++ Dynamic DNS ++ system_status.htm ++ -->
+<script type="text/javascript">//<![CDATA[
+ // helper to move status data to the relevant
+ // screen objects
+ // called by XHR.poll and XHR.get
+ function _data2elements(x, data) {
+ var tbl = document.getElementById('ddns_status_table');
+ // security check
+ if ( !(tbl) ) { return; }
+
+ // clear all rows
+ while (tbl.rows.length > 1)
+ tbl.deleteRow(1);
+
+ // variable for Modulo-Division use to set cbi-rowstyle-? (0 or 1)
+ var x = -1;
+ var i = 1;
+
+ // no data => no ddns-scripts Version 2 installed
+ if ( !data ) {
+ var txt = '<br /><strong><font color="red"><%:Old version of ddns-scripts installed%></font>' ;
+ var url = '<a href="' ;
+ url += '<%=luci.dispatcher.build_url("admin", "system", "packages")%>' ;
+ url += '"><%:install update here%></a></strong>' ;
+ var tr = tbl.insertRow(-1);
+ tr.className = 'cbi-section-table-row cbi-rowstyle-' + (((i + x) % 2) + 1);
+ var td = tr.insertCell(-1);
+ td.colSpan = 2 ;
+ td.innerHTML = txt + " - " + url
+ tr.insertCell(-1).colSpan = 3 ;
+ return;
+ }
+
+ // DDNS Service disabled
+ if (data[0].enabled == 0) {
+ var txt = '<strong><font color="red"><%:DDNS Autostart disabled%></font>' ;
+ var url = '<a href="' + data[0].url_up + '"><%:enable here%></a></strong>' ;
+ var tr = tbl.insertRow(-1);
+ tr.className = 'cbi-section-table-row cbi-rowstyle-' + (((i + x) % 2) + 1);
+ var td = tr.insertCell(-1);
+ td.colSpan = 2 ;
+ td.innerHTML = txt + " - " + url
+ tr.insertCell(-1).colSpan = 3 ;
+ x++ ;
+ }
+
+ for( i = 1; i < data.length; i++ )
+ {
+ var tr = tbl.insertRow(-1);
+ tr.className = 'cbi-section-table-row cbi-rowstyle-' + (((i + x) % 2) + 1) ;
+
+ // configuration
+ tr.insertCell(-1).innerHTML = '<strong>' + data[i].section + '</strong>' ;
+
+ // pid
+ // data[i].pid ignored here
+
+ // last update
+ // data[i].datelast ignored here
+
+ // next update
+ switch (data[i].datenext) {
+ case "_empty_":
+ tr.insertCell(-1).innerHTML = '<em><%:Unknown error%></em>' ;
+ break;
+ case "_stopped_":
+ tr.insertCell(-1).innerHTML = '<em><%:Stopped%></em>' ;
+ break;
+ case "_disabled_":
+ tr.insertCell(-1).innerHTML = '<em><%:Disabled%></em>' ;
+ break;
+ case "_noupdate_":
+ tr.insertCell(-1).innerHTML = '<em><%:Update error%></em>' ;
+ break;
+ case "_runonce_":
+ tr.insertCell(-1).innerHTML = '<em><%:Run once%></em>' ;
+ break;
+ case "_verify_":
+ tr.insertCell(-1).innerHTML = '<em><%:Verify%></em>';
+ break;
+ default:
+ tr.insertCell(-1).innerHTML = data[i].datenext ;
+ break;
+ }
+
+ // domain
+ if (data[i].domain == "_nodomain_")
+ tr.insertCell(-1).innerHTML = '<em><%:config error%></em>';
+ else
+ tr.insertCell(-1).innerHTML = data[i].domain;
+
+ // registered IP
+ switch (data[i].reg_ip) {
+ case "_nodomain_":
+ tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
+ break;
+ case "_nodata_":
+ tr.insertCell(-1).innerHTML = '<em><%:No data%></em>';
+ break;
+ case "_noipv6_":
+ tr.insertCell(-1).innerHTML = '<em><%:IPv6 not supported%></em>';
+ break;
+ default:
+ tr.insertCell(-1).innerHTML = data[i].reg_ip;
+ break;
+ }
+
+ // monitored interfacce
+ if (data[i].iface == "_nonet_")
+ tr.insertCell(-1).innerHTML = '<em><%:Config error%></em>';
+ else
+ tr.insertCell(-1).innerHTML = data[i].iface;
+ }
+
+ if (tbl.rows.length == 1 || (data[0].enabled == 0 && tbl.rows.length == 2) ) {
+ var br = '<br />';
+ if (tbl.rows.length > 1)
+ br = '';
+ var tr = tbl.insertRow(-1);
+ tr.className = "cbi-section-table-row";
+ var td = tr.insertCell(-1);
+ td.colSpan = 5;
+ td.innerHTML = '<em>' + br + '<%:There is no service configured.%></em>' ;
+ }
+ }
+
+ // force to immediate show status (not waiting for XHR.poll)
+ XHR.get('<%=luci.dispatcher.build_url("admin", "services", "ddns", "status")%>', null,
+ function(x, data) {
+ _data2elements(x, data);
+ }
+ );
+
+ XHR.poll(10, '<%=luci.dispatcher.build_url("admin", "services", "ddns", "status")%>', null,
+ function(x, data) {
+ _data2elements(x, data);
+ }
+ );
+//]]></script>
+
+<fieldset class="cbi-section" id="ddns_status_section">
+ <legend><a href="<%=luci.dispatcher.build_url([[admin]], [[services]], [[ddns]])%>"><%:Dynamic DNS%></a></legend>
+
+ <table class="cbi-section-table" id="ddns_status_table">
+ <tr class="cbi-section-table-titles">
+ <th class="cbi-section-table-cell"><%:Configuration%></th>
+ <th class="cbi-section-table-cell"><%:Next Update%></th>
+ <th class="cbi-section-table-cell"><%:Hostname/Domain%></th>
+ <th class="cbi-section-table-cell"><%:Registered IP%></th>
+ <th class="cbi-section-table-cell"><%:Network%></th>
+ </tr>
+ <tr class="cbi-section-table-row">
+ <td colspan="5"><em><br /><%:Collecting data...%></em></td>
+ </tr>
+ </table>
+</fieldset>
+<!-- ++ END ++ Dynamic DNS ++ system_status.htm ++ -->