-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fc50840
Showing
6 changed files
with
477 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ulmus | ||
|
||
A proof of concept WordPress theme written in Elm. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"version": "1.0.0", | ||
"summary": "helpful summary of your project, less than 80 characters", | ||
"repository": "https://github.com/user/project.git", | ||
"license": "BSD3", | ||
"source-directories": [ | ||
"src" | ||
], | ||
"exposed-modules": [], | ||
"native-modules": true, | ||
"dependencies": { | ||
"elm-lang/core": "5.0.0 <= v < 6.0.0", | ||
"elm-lang/dom": "1.1.1 <= v < 2.0.0", | ||
"elm-lang/html": "2.0.0 <= v < 3.0.0", | ||
"elm-lang/http": "1.0.0 <= v < 2.0.0", | ||
"elm-lang/navigation": "2.0.1 <= v < 3.0.0", | ||
"evancz/elm-markdown": "3.0.1 <= v < 4.0.0", | ||
"evancz/url-parser": "2.0.1 <= v < 3.0.0" | ||
}, | ||
"elm-version": "0.18.0 <= v < 0.19.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
/** | ||
* Ulmus functions and definitions. | ||
* | ||
* @link https://developer.wordpress.org/themes/basics/theme-functions/ | ||
* | ||
* @package Ulmus | ||
*/ | ||
|
||
if ( ! function_exists( 'ulmus_setup' ) ) : | ||
/** | ||
* Sets up theme defaults and registers support for various WordPress features. | ||
* | ||
* Note that this function is hooked into the after_setup_theme hook, which | ||
* runs before the init hook. The init hook is too late for some features, such | ||
* as indicating support for post thumbnails. | ||
*/ | ||
function ulmus_setup() { | ||
/* | ||
* Make theme available for translation. | ||
* Translations can be filed in the /languages/ directory. | ||
* If you're building a theme based on Ulmus, use a find and replace | ||
* to change 'ulmus' to the name of your theme in all the template files. | ||
*/ | ||
load_theme_textdomain( 'ulmus', get_template_directory(). '/languages' ); | ||
|
||
// Add default posts and comments RSS feed links to head. | ||
add_theme_support( 'automatic-feed-links' ); | ||
|
||
/* | ||
* Let WordPress manage the document title. | ||
* By adding theme support, we declare that this theme does not use a | ||
* hard-coded <title> tag in the document head, and expect WordPress to | ||
* provide it for us. | ||
*/ | ||
add_theme_support( 'title-tag' ); | ||
|
||
/* | ||
* Enable support for Post Thumbnails on posts and pages. | ||
* | ||
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/ | ||
* | ||
*/ | ||
add_theme_support( 'post-thumbnails' ); | ||
} | ||
endif; | ||
add_action( 'after_setup_theme', 'ulmus_setup' ); | ||
|
||
/** | ||
* Enqueue scripts and styles. | ||
*/ | ||
function ulmus_scripts() { | ||
wp_enqueue_style( 'ulmus-style', get_stylesheet_uri() ); | ||
|
||
wp_enqueue_script( 'ulmus-theme', get_template_directory_uri() . '/ulmus.js', array(), '20170118', true ); | ||
} | ||
add_action( 'wp_enqueue_scripts', 'ulmus_scripts' ); | ||
|
||
function get_post_data( $posts = null ) { | ||
//if ( $posts === null && ! is_404() ) { | ||
$posts = $GLOBALS['wp_query']->posts; | ||
//} | ||
//error_log( print_r( $GLOBALS['wp_query']->posts, true ) ); | ||
global $wp_rest_server; | ||
if ( empty( $wp_rest_server ) ) { | ||
$wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' ); | ||
$wp_rest_server = new $wp_rest_server_class; | ||
do_action( 'rest_api_init' ); | ||
} | ||
$data = array(); | ||
$request = new \WP_REST_Request(); | ||
$request['context'] = 'view'; | ||
foreach ( (array) $posts as $post ) { | ||
$controller = new \WP_REST_Posts_Controller( $post->post_type ); | ||
$data[] = $wp_rest_server->response_to_data( $controller->prepare_item_for_response( $post, $request ), true ); | ||
} | ||
error_log( print_r( $data, true ) ); | ||
return $data; | ||
} | ||
|
||
add_action( 'wp_footer', 'get_post_data' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
/** | ||
* The header for our theme. | ||
* | ||
* This is the template that displays all of the <head> section and everything up until <div id="content"> | ||
* | ||
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials | ||
* | ||
* @package Ulmus | ||
*/ | ||
|
||
?><!DOCTYPE html> | ||
<html <?php language_attributes(); ?>> | ||
<head> | ||
<meta charset="<?php bloginfo( 'charset' ); ?>"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<link rel="profile" href="http://gmpg.org/xfn/11"> | ||
|
||
<?php wp_head(); ?> | ||
</head> | ||
|
||
<body id="body" <?php body_class(); ?>> | ||
|
||
|
||
<?php wp_footer(); ?> | ||
|
||
<script> | ||
var node = document.getElementById( 'body' ); | ||
var app = Elm.Ulmus.embed( node ); | ||
app.ports.wpOptions.send( 'http://wp-rest-api-demo.dev/wp-json/wp/v2/posts' ); | ||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
port module Ulmus exposing (..) | ||
|
||
import Dom.Scroll exposing (toTop) | ||
import Html exposing (..) | ||
import Html.Attributes exposing (..) | ||
import Html.Events exposing (onClick, onWithOptions) | ||
import Http | ||
import Json.Decode as Decode exposing (Decoder, field, at, succeed) | ||
import Markdown | ||
import Navigation | ||
import UrlParser as Url exposing((</>), (<?>), s, int, string, stringParam, top) | ||
|
||
|
||
-- MODEL | ||
|
||
type alias Model = | ||
{ route : Route | ||
, history : List (Maybe Route) | ||
, posts : List Post | ||
, havePosts : Bool | ||
, apiUrl : String | ||
} | ||
|
||
|
||
type alias Post = | ||
{ id : Int | ||
, date : String | ||
, slug : String | ||
, link : String | ||
, content : String | ||
, title : String | ||
} | ||
|
||
|
||
initialModel : Route -> Model | ||
initialModel route = | ||
{ route = route | ||
, history = [] | ||
, posts = [] | ||
, havePosts = False | ||
, apiUrl = "" | ||
} | ||
|
||
init : Navigation.Location -> ( Model, Cmd Msg ) | ||
init location = | ||
let | ||
currentRoute = | ||
parseLocation location | ||
in | ||
( initialModel currentRoute, Cmd.none ) | ||
|
||
|
||
-- URL PARSING | ||
|
||
|
||
type Route | ||
= Home | ||
| BlogPost Int Int Int String | ||
| NotFoundRoute | ||
|
||
|
||
type alias PostRoute = { year : Int, month : Int, day : Int, slug : String } | ||
|
||
|
||
rawPost : Url.Parser (Int -> Int -> Int -> String -> slug) slug | ||
rawPost = | ||
int </> int </> int </> string | ||
|
||
|
||
route : Url.Parser (Route -> a) a | ||
route = | ||
Url.oneOf | ||
[ Url.map Home top | ||
, Url.map BlogPost rawPost | ||
] | ||
|
||
|
||
parseLocation : Navigation.Location -> Route | ||
parseLocation location = | ||
case (Url.parsePath route location) of | ||
Just route -> | ||
route | ||
|
||
Nothing -> | ||
NotFoundRoute | ||
|
||
|
||
-- UPDATE | ||
|
||
|
||
type Msg = | ||
GetPosts (Result Http.Error (List Post)) | ||
| ApiUrl (String) | ||
| NewUrl String | ||
| UrlChange Navigation.Location | ||
| NoOp | ||
|
||
|
||
update : Msg -> Model -> ( Model, Cmd Msg ) | ||
update msg model = | ||
case msg of | ||
GetPosts (Ok latestPosts) -> | ||
( { model | posts = latestPosts, havePosts = True }, Cmd.none ) | ||
|
||
GetPosts (Err error) -> | ||
let | ||
_ = Debug.log "Oops!" error | ||
in | ||
(model, Cmd.none) | ||
|
||
ApiUrl newApiUrl -> | ||
( { model | apiUrl = newApiUrl }, getPosts newApiUrl) | ||
|
||
NewUrl url -> | ||
( model | ||
, Navigation.newUrl url | ||
) | ||
|
||
UrlChange location -> | ||
let | ||
newRoute = | ||
parseLocation location | ||
in | ||
( { model | route = newRoute }, Cmd.none ) | ||
|
||
NoOp -> | ||
( model, Cmd.none ) | ||
|
||
|
||
-- DECODERS | ||
|
||
postDecoder : Decoder Post | ||
postDecoder = | ||
Decode.map6 Post | ||
(field "id" Decode.int) | ||
(field "date" Decode.string) | ||
(field "slug" Decode.string) | ||
(field "link" Decode.string) | ||
(at ["content", "rendered"] Decode.string) | ||
(at ["title", "rendered"] Decode.string) | ||
|
||
|
||
-- COMMANDS | ||
|
||
getPosts : String -> Cmd Msg | ||
getPosts apiUrl = | ||
(Decode.list postDecoder) | ||
|> Http.get (apiUrl ++ "posts") | ||
|> Http.send GetPosts | ||
|
||
|
||
onPrevDefClick : msg -> Attribute msg | ||
onPrevDefClick message = | ||
onWithOptions "click" { stopPropagation = True, preventDefault = True } (Decode.succeed message) | ||
|
||
|
||
-- SUBSCRIPTIONS | ||
|
||
port apiUrl : (String -> msg) -> Sub msg | ||
|
||
subscriptions : Model -> Sub Msg | ||
subscriptions model = | ||
apiUrl ApiUrl | ||
|
||
|
||
-- VIEW | ||
|
||
view : Model -> Html Msg | ||
view model = | ||
div [ id "page", class "site" ] | ||
[ div [ class "content" ] | ||
[ header [ id "masthead", class "site-header" ] | ||
[ div [ class "site-branding" ] | ||
[ h1 [ class "site-title" ] [ | ||
a [ href "/", onPrevDefClick (NewUrl "/") ] | ||
[ text "WordPress ♥ Elm ♥ REST API" ] | ||
] | ||
] | ||
] | ||
, page model | ||
] | ||
] | ||
|
||
page : Model -> Html Msg | ||
page model = | ||
case model.route of | ||
Home -> | ||
viewPostList model.posts | ||
|
||
BlogPost year month day slug -> | ||
viewSinglePost model slug | ||
|
||
NotFoundRoute -> | ||
viewNotFound | ||
|
||
|
||
viewPostList : List Post -> Html Msg | ||
viewPostList posts = | ||
let | ||
listOfPosts = | ||
List.map viewPost posts | ||
in | ||
div [] listOfPosts | ||
|
||
|
||
viewSinglePost : Model -> String -> Html Msg | ||
viewSinglePost model slug = | ||
let | ||
maybePost = | ||
model.posts | ||
|> List.filter (\post -> post.slug == slug) | ||
|> List.head | ||
in | ||
case maybePost of | ||
Just post -> | ||
div [] [ viewPost post ] | ||
|
||
Nothing -> | ||
viewNotFound | ||
|
||
|
||
viewPost : Post -> Html Msg | ||
viewPost post = | ||
section [ class "post" ] | ||
[ h2 [] [ | ||
a [ href post.link, onPrevDefClick (NewUrl post.link) ] | ||
[ text post.title ] | ||
] | ||
, article [ class "content"] | ||
[ Markdown.toHtml [] post.content ] | ||
] | ||
|
||
|
||
viewNotFound : Html Msg | ||
viewNotFound = | ||
div [] | ||
[ text "Not found" ] | ||
|
||
|
||
main : Program Never Model Msg | ||
main = | ||
Navigation.program UrlChange | ||
{ init = init | ||
, view = view | ||
, update = update | ||
, subscriptions = subscriptions | ||
} |
Oops, something went wrong.