如何在 Prolog 中将 CSS(带查询结果)添加到动态 reply_html_page 中?
How to add CSS (w/ query results) into dynamic reply_html_page in Prolog?
我真的很难过渡到 Prolog 中的编码。当用户从网页提交数据时,我会尝试 return 一个新页面,显示基于用户提交内容的查询结果。这是我到目前为止所拥有的。
编辑:(为完整源代码截取的替换代码)
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_error)).
:- use_module(library(http/html_write)).
:- use_module(library(http/http_client)).
:- use_module(library(http/http_parameters)).
:- use_module(library(http/html_head)).
:- use_module(library(http/http_server_files)).
:- use_module(parts, [part/4]).
:- http_handler(root(.), main_query, []).
:- http_handler(root(search), search, []).
:- http_handler(root(search), part_results, []).
http:location(css, root(css), []).
server(Port) :-
http_server(http_dispatch, [port(Port)]).
:- multifile
user:body//2.
user:body(part_style, Body) -->
html(body([
div([id(top)], ['Parts']),
div(id(content), Body)
])).
main_query(Request) :-
reply_html_page(
part_style,
title('Beta Query'),
[\page_content(Request)]).
page_content(_Request) -->
{ http_link_to_id(search, [], Ref) },
html([ \html_requires(css('part-style.css')),
form([id(search), action='/search', method='POST'], [
div([id(search_table)], [
div([class(search_cell)], [
label([for=part], ' '),
select([name=part], \parts)
]),
div([class(search_cell)], [
label([for=major], ' '),
select([name=major], \majors)
]),
div([class(search_cell)], [
label([for=minor], ' '),
select([name=minor], \minors)
]),
p([], [
input([name=submit, class="button", type=submit,
value='Search'], [])
])
])
])
]).
css(URL) -->
html_post(css,
link([ type('text/css'),
rel('stylesheet'),
href(URL)
])).
part_results(Request) :-
reply_html_page(part_style,
[title('Part Results'),
\css('part-style.css'),
\html_receive(css)]).
% \query_part).
% having trouble truing query_part into DCG.
query_part(Request) :-
member(method(post), Request), !,
http_read_data(Request, Data, []),
format('Content-type: text/html~n~n', []),
format('<p>', []),
memberchk(part=Part, Data),
memberchk(major=M, Data),
memberchk(minor=I, Data),
atom_number(M, Major),
atom_number(I, Minor),
findall(p(Part, Major, Minor, Desc),
part(Part, Major, Minor, Desc), Descriptions),
maplist(desc, Descriptions),
format('</p>'),
format('<a href="http://localhost:8000" class="button">Back</a>').
desc(p(P,M,I,D)) :- format("~q ~q:~q - ~q</br>", [P,M,I,D]).
parts -->
{ findall(P, part(P, Major, Minor, Desc), Parts),
sort(Parts, Sorted) },
options(Sorted).
majors -->
{ findall(M, part(Part, M, Minor, Desc), Majors),
sort(Majors, Sorted) },
options(Sorted).
minors -->
{ findall(I, part(Part, Major, I, Desc), Minors),
sort(Minors, Sorted) },
options(Sorted).
options([]) --> [].
options([O|Os]) -->
html(option([value=O], O)),
options(Os).
试图将此 query_part/1 定义为 DCG 让我很头疼。最初处理程序直接调用 part_query/1,但现在有一个调用 DCG 的 part_results 规则,并且 query_part 我们传递了一个请求参数。我一直在尝试阅读 DCG,但仍然不太了解它们,除了它们应该使编写规则更容易之外,我也不了解如何将 {} 与它们一起使用,我认为我需要这样做。 (但是,DCG 本身超出了这个问题的范围,因为它涵盖了很多,我可以继续尝试在其他地方理解它)。所以我仍在尝试将带有查询结果的 CSS 放入回复页面。
目前,CSS 出现在 HTML 的正文中。
非常感谢任何帮助。
我对此有几点评论:
立即解决
首先,为您的任务提供一个解决方案:要post资源,只需使用css//1
part_results/1
中的非终结符:
part_results(Request) :-
reply_html_page(part_style,
[title('Part Results'),
\css('myfile.css'),
\html_receive(css)],
\query_part).
这足以得到你想要的。您使用 css//1
的方式与您在 HTTP 框架中使用任何其他非终端的方式完全相同,使用 (\)/1
espace 语法。
不同的解决方案
获得几乎相同结果的不同解决方案是使用html_requires//1
:
part_results(Request) :-
reply_html_page(part_style,
[title('Part Results'),
\html_requires(css('my-style.css'))],
\query_part).
这是来自 library(http/html_head)
的一个库谓词,基本上可以完成您当前正在做的事情手动。
请注意,您需要使用 library(http/http_server_files)
来定义资源文件所需的位置。对于 CSS 文件,预定义位置是 root(css)
,因此您需要将 css 文件放在 css/*
中,这与您手动执行的操作不同。
为什么只有 body?
在您的原始示例中,为什么只发出了 body?答:因为你没有发出任何其他东西。
请注意,除了使用 reply_html_page/3
,您还可以简单地 自己在当前输出 上输出整个页面。这当然需要你发出你想要的一切,而不仅仅是body。
一般建议
下次,请 post 一个 self-contained 示例 ,不仅是部分片段,以便其他人更容易尝试您的代码。
这意味着:
- 包括所有必要的库
- 说明如何启动服务器
- 显示如何访问服务器
- 等等
我真的很难过渡到 Prolog 中的编码。当用户从网页提交数据时,我会尝试 return 一个新页面,显示基于用户提交内容的查询结果。这是我到目前为止所拥有的。
编辑:(为完整源代码截取的替换代码)
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_error)).
:- use_module(library(http/html_write)).
:- use_module(library(http/http_client)).
:- use_module(library(http/http_parameters)).
:- use_module(library(http/html_head)).
:- use_module(library(http/http_server_files)).
:- use_module(parts, [part/4]).
:- http_handler(root(.), main_query, []).
:- http_handler(root(search), search, []).
:- http_handler(root(search), part_results, []).
http:location(css, root(css), []).
server(Port) :-
http_server(http_dispatch, [port(Port)]).
:- multifile
user:body//2.
user:body(part_style, Body) -->
html(body([
div([id(top)], ['Parts']),
div(id(content), Body)
])).
main_query(Request) :-
reply_html_page(
part_style,
title('Beta Query'),
[\page_content(Request)]).
page_content(_Request) -->
{ http_link_to_id(search, [], Ref) },
html([ \html_requires(css('part-style.css')),
form([id(search), action='/search', method='POST'], [
div([id(search_table)], [
div([class(search_cell)], [
label([for=part], ' '),
select([name=part], \parts)
]),
div([class(search_cell)], [
label([for=major], ' '),
select([name=major], \majors)
]),
div([class(search_cell)], [
label([for=minor], ' '),
select([name=minor], \minors)
]),
p([], [
input([name=submit, class="button", type=submit,
value='Search'], [])
])
])
])
]).
css(URL) -->
html_post(css,
link([ type('text/css'),
rel('stylesheet'),
href(URL)
])).
part_results(Request) :-
reply_html_page(part_style,
[title('Part Results'),
\css('part-style.css'),
\html_receive(css)]).
% \query_part).
% having trouble truing query_part into DCG.
query_part(Request) :-
member(method(post), Request), !,
http_read_data(Request, Data, []),
format('Content-type: text/html~n~n', []),
format('<p>', []),
memberchk(part=Part, Data),
memberchk(major=M, Data),
memberchk(minor=I, Data),
atom_number(M, Major),
atom_number(I, Minor),
findall(p(Part, Major, Minor, Desc),
part(Part, Major, Minor, Desc), Descriptions),
maplist(desc, Descriptions),
format('</p>'),
format('<a href="http://localhost:8000" class="button">Back</a>').
desc(p(P,M,I,D)) :- format("~q ~q:~q - ~q</br>", [P,M,I,D]).
parts -->
{ findall(P, part(P, Major, Minor, Desc), Parts),
sort(Parts, Sorted) },
options(Sorted).
majors -->
{ findall(M, part(Part, M, Minor, Desc), Majors),
sort(Majors, Sorted) },
options(Sorted).
minors -->
{ findall(I, part(Part, Major, I, Desc), Minors),
sort(Minors, Sorted) },
options(Sorted).
options([]) --> [].
options([O|Os]) -->
html(option([value=O], O)),
options(Os).
试图将此 query_part/1 定义为 DCG 让我很头疼。最初处理程序直接调用 part_query/1,但现在有一个调用 DCG 的 part_results 规则,并且 query_part 我们传递了一个请求参数。我一直在尝试阅读 DCG,但仍然不太了解它们,除了它们应该使编写规则更容易之外,我也不了解如何将 {} 与它们一起使用,我认为我需要这样做。 (但是,DCG 本身超出了这个问题的范围,因为它涵盖了很多,我可以继续尝试在其他地方理解它)。所以我仍在尝试将带有查询结果的 CSS 放入回复页面。
目前,CSS 出现在 HTML 的正文中。
非常感谢任何帮助。
我对此有几点评论:
立即解决
首先,为您的任务提供一个解决方案:要post资源,只需使用css//1
part_results/1
中的非终结符:
part_results(Request) :- reply_html_page(part_style, [title('Part Results'), \css('myfile.css'), \html_receive(css)], \query_part).
这足以得到你想要的。您使用 css//1
的方式与您在 HTTP 框架中使用任何其他非终端的方式完全相同,使用 (\)/1
espace 语法。
不同的解决方案
获得几乎相同结果的不同解决方案是使用html_requires//1
:
part_results(Request) :- reply_html_page(part_style, [title('Part Results'), \html_requires(css('my-style.css'))], \query_part).
这是来自 library(http/html_head)
的一个库谓词,基本上可以完成您当前正在做的事情手动。
请注意,您需要使用 library(http/http_server_files)
来定义资源文件所需的位置。对于 CSS 文件,预定义位置是 root(css)
,因此您需要将 css 文件放在 css/*
中,这与您手动执行的操作不同。
为什么只有 body?
在您的原始示例中,为什么只发出了 body?答:因为你没有发出任何其他东西。
请注意,除了使用 reply_html_page/3
,您还可以简单地 自己在当前输出 上输出整个页面。这当然需要你发出你想要的一切,而不仅仅是body。
一般建议
下次,请 post 一个 self-contained 示例 ,不仅是部分片段,以便其他人更容易尝试您的代码。
这意味着:
- 包括所有必要的库
- 说明如何启动服务器
- 显示如何访问服务器
- 等等