如何将CSS(带有查询结果)添加到Prolog的动态reply_html_page中?

时间:2016-11-05 01:05:13

标签: html prolog swi-prolog

我真的很难过渡到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的正文中显示。

任何帮助都非常感激。

1 个答案:

答案 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。这当然要求你发出你想要的一切,而不仅仅是身体。

一般建议

下次,请发布一个自包含示例,而不仅仅是部分代码段,以便其他人更轻松地尝试您的代码。

这意味着:

  • 包含所有必要的库
  • 说明如何启动服务器
  • 说明如何访问服务器