retype icon indicating copy to clipboard operation
retype copied to clipboard

Allow option to display "last edited/modified" person and date

Open xyeLz opened this issue 2 years ago • 8 comments

A lot of my content relies on the date to show whether it's still relevant or not. I think people appreciate knowing whether my project contents are stale or not (and most of my users won't check GitHub; some probably don't even know my content is publicly available here). It would be great if the option existed for the project owner to determine (perhaps on a project or a page-by-page basis) whether the last edited date should be shown. Additionally, it would be useful (more so for the project owner than the users) if the ability existed to show who that person was.

xyeLz avatar Aug 11 '22 01:08 xyeLz

This is also a feature I have wanted since Day 0. Problem is, none of us have been able to figure out how to accomplish writing this data in an automated process that doesn't introduce multiple levels of complexity and remote calls.

To get this data for a single page, the retypeapp would have to first be authorized to query a git repo, and then query that file for its latest change data. This would have to occur any time the project is built, either locally or using a remote CI service.

Those calls would also add plenty of delay to build process and breaks our prime directive of no remote calls during build.

Could it all be setup? yes, of course. We could also probably add a special command line -- argument to the CLI that would need to be called in order to trigger the remote author/late-updated data. It's all possible but gets real complicated real fast.

There is a way to add this info to the page manually, using the author and date Page configs.

---
author:
  name: Frank Esposito
date: 2022-08-10 # August 10, 2022
---

geoffreymcgill avatar Aug 11 '22 05:08 geoffreymcgill

Another option for the date could be adding something to the footer, although that would have to manually updated, or you could build in some kind of an automated action into your CI process to update on each build.

footer:
  copyright: "© Copyright. Last updated: 2022-08-10."

geoffreymcgill avatar Aug 11 '22 05:08 geoffreymcgill

Suggestion, which favors simplicity and the principle of least knowledge:

How about simply using the File Modification time? This does not assume the existence of git (or any other) source control, and uses the operating system's field that was designed exactly for this purpose.

Obviously, users who are cloning the repo using git, will simply need to run a command that restores the file's modified time from the repository prior to rendering.

This command does that:

git log --pretty=%at --name-status --reverse | perl -ane '($x,$f)=@F;next if !$x;$t=$x,next if !defined($f)||$s{$f};$s{$f}=utime($t,$t,$f),next if $x=~/[AM]/;'

as extracted from this StackOverflow answer

DannyBen avatar Aug 08 '23 12:08 DannyBen

I think the way to get this Last modified value into the generated .html pages will be creating a GitHub action that injects the datatime stamp using either of the following techniques:

Option 1: Inject into the .md before build

  1. Make a temp cache copy of repo
  2. Loop through all the page .md files (this itself is difficult to determine precisely)
  3. Inject the date page config and value into each .md file
  4. Save the cached .md file
  5. Build the project using the temp cache copy of the repo

Option 2: Inject into the .html after build

  1. In each of the generated .html pages, the Retype app would need to add a comment or maybe a meta tag indicating the relative path of the .md file that was used to generate that page
  2. A GitHub action would then need to loop through all the generated .html files and parse for the path value above
  3. The action would then need to verify the .md file exists
  4. Using git log or other command, extract the File Modification time or some other data that contains the datetime value we need
  5. Format the value using an HTML template
  6. Find the correct position for the Last modified: value in the generated .html file
  7. Inject that compiled template into the correct position
  8. Remove the comment/metatag from Step 1
  9. Save the newly modified .html file

Step 1 is not currently being injected by Retype. As a temp work around, manually adding an HTML <!-- /guides/getting-started.md --> comment or add using the data config should be enough to at least stub out the remaining steps.


Either technique would only work with the page .md files. Revising the content of an include or any other dynamic content would not trigger the last updated value to change, even though the content of the generated .html page might actually be changing in that case.

As well, any change to the page .md file would trigger the last updated value to update, including revising any of the page meta data.

Both of the techniques require a GitHub action/workflow and happen outside of the scope of the actual retypeapp.

Just some thoughts. Let me know what you think.

geoffreymcgill avatar Aug 08 '23 19:08 geoffreymcgill

Just some thoughts. Let me know what you think.

Sorry, I don't like this at all. This is an over-engineered, tightly coupled (not not only with git, but with GitHub Actions), complex solution.

I understand going for the complex solution when there is none other, but this is not the case.

What is wrong with this?

  1. At page render time, take the file mtime of the .md, and inject it to the footer if there is a {{ mtime }} field in it.
  2. In the official Retype github action, run the command to restore mtimes of all files.

DannyBen avatar Aug 09 '23 03:08 DannyBen

What is wrong with this?

I believe cloning a repo sets/resets the LastModifiedTime value of the file on the client.

The only way I know to get an accurate and reliable value is using git log to pull the Author Date.

The following script loops through all the .md files in a folder (project) and logs the file name and author date (%ad):

git ls-files '*.md' | while read file; do
  date=$(git log -1 --format="%ad" --date=format:"%Y-%m-%d" -- "$file")
  printf "%-50s %s\n" "$file" "$date"
done

The above logs the following for the retype project:

LICENSE.md                                         2023-07-31
README.md                                          2023-08-02
_includes/bottom.md                                2023-08-02
_includes/snippets/contact-us.md                   2023-08-01
_includes/snippets/default-pages.md                2023-07-24
_includes/snippets/simple-code-sample.md           2023-04-25
_includes/top.md                                   2023-07-05
about.md                                           2023-08-03
components/alert.md                                2023-04-18
components/badge.md                                2023-04-18
components/button.md                               2023-04-18
components/code-block.md                           2023-08-03
components/code-snippet.md                         2023-08-03
components/column.md                               2023-04-18
components/container.md                            2023-07-25
components/embed.md                                2023-04-18
components/emoji.md                                2023-05-31
components/file-download.md                        2023-08-03
components/icon.md                                 2023-07-05
components/image-alignment-demo.md                 2022-03-31
components/image.md                                2023-07-26
components/list.md                                 2023-04-18
components/math-formulas.md                        2023-08-03
components/mermaid.md                              2023-07-17
components/octicons.md                             2023-07-27
components/panel.md                                2023-05-30
components/readme.md                               2023-08-03
components/reference-link.md                       2023-08-03
components/tab.md                                  2023-04-18
components/table.md                                2023-07-27
configuration/envvars.md                           2023-07-23
configuration/folder.md                            2023-07-26
configuration/page.md                              2023-07-24
configuration/project.md                           2023-08-02
configuration/reserved_words.md                    2023-07-27
faq.md                                             2023-07-26
guides/cli.md                                      2023-05-31
guides/formatting.md                               2023-05-31
guides/getting-started.md                          2023-07-27
guides/github-actions.md                           2023-06-09
hosting/cloudflare.md                              2023-05-04
hosting/docker.md                                  2023-08-08
hosting/git-ftp.md                                 2023-06-09
hosting/github-pages.md                            2023-08-08
hosting/gitlab-pages.md                            2023-08-08
hosting/netlify.md                                 2023-08-08
hosting/web-server.md                              2023-05-31
pro/pro.md                                         2023-08-01
roadmap.md                                         2023-08-03
samples/_includes/basic-page.md                    2022-03-27
samples/_includes/page-with-header.md              2022-03-28
samples/advanced-project-config.md                 2023-05-31
samples/basic-page.md                              2022-03-27
samples/basic-project-config.md                    2023-05-31
samples/page-with-header.md                        2022-03-27

geoffreymcgill avatar Aug 09 '23 04:08 geoffreymcgill

I believe cloning a repo sets/resets the LastModifiedTime value of the file on the client.

You must have missed my previous comment: https://github.com/retypeapp/retype/issues/383#issuecomment-1669505532

It is easier to add this command to your official github action, after git clone, before build, than to implement everything you mentioned, and create an implementation so tightly coupled with things it shouldn't be coupled with.

git log --pretty=%at --name-status --reverse | perl -ane '($x,$f)=@F;next if !$x;$t=$x,next if !defined($f)||$s{$f};$s{$f}=utime($t,$t,$f),next if $x=~/[AM]/;'

DannyBen avatar Aug 09 '23 04:08 DannyBen

okay, yes, this has potential. I'll see if we can make this all work.

geoffreymcgill avatar Aug 09 '23 04:08 geoffreymcgill