我真的很难过渡到Prolog中的编码。当用户从网页提交数据时,我会尝试根据用户提交的内容返回显示查询结果的新页面。这是我到目前为止所拥有的。
修改 :(替换为完整来源修剪的代码)
:- 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我们传递了一个Request arg。我一直在尝试阅读DCG,但仍然不太了解它们,除了它们应该使编写规则更容易,我也不理解如何使用它们,我认为我需要这样做。 (但是,DCG本身不属于这个问题的范围,因为它涵盖了很多,我可以继续尝试在别处理解它)。所以我仍然试图将带有查询结果的CSS放入回复页面。
目前,CSS正在HTML的正文中显示。
任何帮助都非常感激。
答案 0 :(得分:1)
我对此有几点评论:
首先,为您的任务提供解决方案:要发布资源,只需使用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
的方式与使用(\)/1
espace语法时在HTTP框架中使用任何其他非终结符的方式完全相同。
一个不同的解决方案来获得几乎相同的结果是使用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 ?答案:因为你没有发出任何其他东西。
请注意,您可以简单地在当前输出上自行发出整个页面,而不是使用reply_html_page/3
。这当然要求你发出你想要的一切,而不仅仅是身体。
下次,请发布一个自包含示例,而不仅仅是部分代码段,以便其他人更轻松地尝试您的代码。
这意味着: