mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-26 21:36:02 +08:00
Prepare to make Explore section extensible (#626)
This commit is contained in:
parent
3ab2a56924
commit
b930d8620a
3 changed files with 81 additions and 107 deletions
|
|
@ -1,50 +1,3 @@
|
|||
defmodule Livebook.Notebook.Explore.Utils do
|
||||
@moduledoc false
|
||||
|
||||
@doc """
|
||||
Defines a module attribute `attr` with notebook info.
|
||||
"""
|
||||
defmacro defnotebook(attr, props) do
|
||||
quote bind_quoted: [attr: attr, props: props] do
|
||||
{path, notebook_info} = Livebook.Notebook.Explore.Utils.fetch_notebook!(attr, props)
|
||||
|
||||
@external_resource path
|
||||
|
||||
Module.put_attribute(__MODULE__, attr, notebook_info)
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_notebook!(attr, props) do
|
||||
name = Atom.to_string(attr)
|
||||
path = Path.join([__DIR__, "explore", name <> ".livemd"])
|
||||
|
||||
markdown = File.read!(path)
|
||||
# Parse the file to ensure no warnings and read the title.
|
||||
# However, in the info we keep just the file contents to save on memory.
|
||||
{notebook, []} = Livebook.LiveMarkdown.Import.notebook_from_markdown(markdown)
|
||||
|
||||
images =
|
||||
props
|
||||
|> Keyword.get(:image_names, [])
|
||||
|> Map.new(fn image_name ->
|
||||
path = Path.join([__DIR__, "explore", "images", image_name])
|
||||
content = File.read!(path)
|
||||
{image_name, content}
|
||||
end)
|
||||
|
||||
notebook_info = %{
|
||||
slug: String.replace(name, "_", "-"),
|
||||
livemd: markdown,
|
||||
title: notebook.name,
|
||||
description: Keyword.fetch!(props, :description),
|
||||
image_url: Keyword.fetch!(props, :image_url),
|
||||
images: images
|
||||
}
|
||||
|
||||
{path, notebook_info}
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Livebook.Notebook.Explore do
|
||||
@moduledoc false
|
||||
|
||||
|
|
@ -58,78 +11,99 @@ defmodule Livebook.Notebook.Explore do
|
|||
end
|
||||
end
|
||||
|
||||
import Livebook.Notebook.Explore.Utils
|
||||
|
||||
defnotebook(:intro_to_livebook,
|
||||
description: "Get to know Livebook, see how it works and explore its features.",
|
||||
image_url: "/images/logo.png"
|
||||
)
|
||||
|
||||
defnotebook(:distributed_portals_with_elixir,
|
||||
description:
|
||||
"A fast-paced introduction to the Elixir language by building distributed data-transfer portals.",
|
||||
image_url: "/images/elixir-portal.jpeg",
|
||||
image_names: ["portal-drop.jpeg", "portal-list.jpeg"]
|
||||
)
|
||||
|
||||
defnotebook(:elixir_and_livebook,
|
||||
description: "Learn how to use some of Elixir and Livebook's unique features together.",
|
||||
image_url: "/images/elixir.png"
|
||||
)
|
||||
|
||||
defnotebook(:intro_to_nx,
|
||||
description:
|
||||
"Enter Numerical Elixir, experience the power of multi-dimensional arrays of numbers.",
|
||||
image_url: "/images/nx.png"
|
||||
)
|
||||
|
||||
defnotebook(:intro_to_axon,
|
||||
description: "Build Neural Networks in Elixir using a high-level, composable API.",
|
||||
image_url: "/images/axon.png"
|
||||
)
|
||||
|
||||
defnotebook(:intro_to_vega_lite,
|
||||
description: "Learn how to quickly create numerous plots for your data.",
|
||||
image_url: "/images/vega_lite.png"
|
||||
)
|
||||
|
||||
defnotebook(:vm_introspection,
|
||||
description: "Extract and visualize information about a remote running node.",
|
||||
image_url: "/images/vm_introspection.png"
|
||||
)
|
||||
|
||||
defnotebook(:intro_to_kino,
|
||||
description: "Display and control rich and interactive widgets in Livebook.",
|
||||
image_url: "/images/kino.png"
|
||||
)
|
||||
|
||||
@type notebook_info :: %{
|
||||
slug: String.t(),
|
||||
livemd: String.t(),
|
||||
title: String.t(),
|
||||
description: String.t(),
|
||||
image_url: String.t(),
|
||||
cover_url: String.t(),
|
||||
images: images()
|
||||
}
|
||||
|
||||
@type images :: %{String.t() => binary()}
|
||||
|
||||
infos = [
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/intro_to_livebook.livemd"),
|
||||
description: "Get to know Livebook, see how it works and explore its features.",
|
||||
cover_url: "/images/logo.png"
|
||||
},
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/distributed_portals_with_elixir.livemd"),
|
||||
description:
|
||||
"A fast-paced introduction to the Elixir language by building distributed data-transfer portals.",
|
||||
cover_url: "/images/elixir-portal.jpeg",
|
||||
image_names: ["portal-drop.jpeg", "portal-list.jpeg"]
|
||||
},
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/elixir_and_livebook.livemd"),
|
||||
description: "Learn how to use some of Elixir and Livebook's unique features together.",
|
||||
cover_url: "/images/elixir.png"
|
||||
},
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/intro_to_vega_lite.livemd"),
|
||||
description: "Learn how to quickly create numerous plots for your data.",
|
||||
cover_url: "/images/vega_lite.png"
|
||||
},
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/intro_to_kino.livemd"),
|
||||
description: "Display and control rich and interactive widgets in Livebook.",
|
||||
cover_url: "/images/kino.png"
|
||||
},
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/intro_to_nx.livemd"),
|
||||
description:
|
||||
"Enter Numerical Elixir, experience the power of multi-dimensional arrays of numbers.",
|
||||
cover_url: "/images/nx.png"
|
||||
},
|
||||
# %{
|
||||
# path: Path.join(__DIR__, "explore/intro_to_axon.livemd"),
|
||||
# description: "Build Neural Networks in Elixir using a high-level, composable API.",
|
||||
# cover_url: "/images/axon.png"
|
||||
# },
|
||||
%{
|
||||
path: Path.join(__DIR__, "explore/vm_introspection.livemd"),
|
||||
description: "Extract and visualize information about a remote running node.",
|
||||
cover_url: "/images/vm_introspection.png"
|
||||
}
|
||||
]
|
||||
|
||||
notebook_infos =
|
||||
for info <- infos do
|
||||
path = Map.fetch!(info, :path)
|
||||
@external_resource path
|
||||
|
||||
markdown = File.read!(path)
|
||||
# Parse the file to ensure no warnings and read the title.
|
||||
# However, in the info we keep just the file contents to save on memory.
|
||||
{notebook, []} = Livebook.LiveMarkdown.Import.notebook_from_markdown(markdown)
|
||||
|
||||
images =
|
||||
info
|
||||
|> Map.get(:image_names, [])
|
||||
|> Map.new(fn image_name ->
|
||||
path = Path.join([Path.dirname(path), "images", image_name])
|
||||
content = File.read!(path)
|
||||
{image_name, content}
|
||||
end)
|
||||
|
||||
slug = info[:slug] || path |> Path.basename() |> Path.rootname() |> String.replace("_", "-")
|
||||
|
||||
%{
|
||||
slug: slug,
|
||||
livemd: markdown,
|
||||
title: notebook.name,
|
||||
description: Map.fetch!(info, :description),
|
||||
cover_url: Map.fetch!(info, :cover_url),
|
||||
images: images
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns a list of example notebooks with metadata.
|
||||
"""
|
||||
@spec notebook_infos() :: list(notebook_info())
|
||||
def notebook_infos() do
|
||||
[
|
||||
@intro_to_livebook,
|
||||
@distributed_portals_with_elixir,
|
||||
@elixir_and_livebook,
|
||||
@intro_to_vega_lite,
|
||||
@intro_to_kino,
|
||||
@intro_to_nx,
|
||||
@vm_introspection
|
||||
# , @intro_to_axon
|
||||
]
|
||||
end
|
||||
def notebook_infos(), do: unquote(Macro.escape(notebook_infos))
|
||||
|
||||
@doc """
|
||||
Finds explore notebook by slug and returns the parsed data structure.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defmodule LivebookWeb.ExploreHelpers do
|
|||
<div class="flex flex-col">
|
||||
<%= live_redirect to: Routes.explore_path(@socket, :notebook, @notebook_info.slug),
|
||||
class: "flex items-center justify-center p-6 border-2 border-gray-100 rounded-t-2xl h-[150px]" do %>
|
||||
<img src={@notebook_info.image_url} class="max-h-full max-w-[75%]" />
|
||||
<img src={@notebook_info.cover_url} class="max-h-full max-w-[75%]" />
|
||||
<% end %>
|
||||
<div class="px-6 py-4 bg-gray-100 rounded-b-2xl flex-grow">
|
||||
<%= live_redirect @notebook_info.title,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ defmodule LivebookWeb.ExploreLive do
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex-grow hidden md:flex flex items-center justify-center">
|
||||
<img src={@lead_notebook_info.image_url} height="120" width="120" alt="livebook" />
|
||||
<img src={@lead_notebook_info.cover_url} height="120" width="120" alt="livebook" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue